Bug 330938 - Merge Eclipse Incubator with e4

Proovide the converted platform incubator repo

Merge remote branch 'inc/master'

Conflicts:
	.gitignore
diff --git a/bundles/org.eclipse.e4.core.javascript/.classpath b/bundles/org.eclipse.e4.core.javascript/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.core.javascript/.project b/bundles/org.eclipse.e4.core.javascript/.project
new file mode 100644
index 0000000..4a3a255
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.core.javascript</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.core.javascript/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.core.javascript/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..46c764e
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Nov 26 21:57:11 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.core.javascript/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.core.javascript/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..36749d6
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Javascript Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.core.javascript;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.core.runtime;bundle-version="3.4.0",
+ org.mozilla.javascript;bundle-version="1.6.6",
+ org.eclipse.e4.core.contexts,
+ org.eclipse.e4.core.di
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.core.javascript/build.properties b/bundles/org.eclipse.e4.core.javascript/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/bundles/org.eclipse.e4.core.javascript/plugin.xml b/bundles/org.eclipse.e4.core.javascript/plugin.xml
new file mode 100644
index 0000000..f333964
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/plugin.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+  <extension
+        point="org.eclipse.e4.languages">
+     <language
+           contributionFactory="org.eclipse.e4.demo.javascript.JSContributionFactory"
+           name="js">
+     </language>
+  </extension>
+</plugin>
diff --git a/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSContributionFactory.java b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSContributionFactory.java
new file mode 100644
index 0000000..d3a5430
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSContributionFactory.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.javascript;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.WeakHashMap;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.services.contributions.IContributionFactorySpi;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Bundle;
+
+public class JSContributionFactory implements IContributionFactorySpi {
+
+	private JSUtil js;
+	private WeakHashMap contributionDatas = new WeakHashMap();
+
+	public JSContributionFactory() {
+		js = new JSUtil();
+	}
+
+	private static class ContributionWrapper {
+		Object contribution;
+
+		public ContributionWrapper(Object c) {
+			contribution = c;
+		}
+	}
+
+	private static class ContributionData {
+		Bundle bundle;
+		String name;
+		String script;
+		IEclipseContext context;
+
+		private Object updateContribution(JSUtil js, Object contribution) {
+			InputStream stream;
+			try {
+				stream = bundle.getResource(name).openStream();
+				String newScript = readString(stream);
+				if (script != null && script.equals(newScript)) {
+					return contribution;
+				}
+				script = newScript;
+				contribution = js.eval(script);
+				Object initargs = js.get(contribution, "initargs");
+				if (initargs instanceof Scriptable) {
+					int len = js.length(initargs);
+					Object[] args = new Object[len];
+					for (int i = 0; i < len; i++) {
+						args[i] = context.get((String) js.get(initargs, i));
+					}
+					js.call(js.get(contribution, "init"), contribution, args);
+				}
+				return contribution;
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return null;
+		}
+
+	}
+
+	private static String readString(InputStream is) throws IOException {
+		StringBuffer result = new StringBuffer();
+		BufferedInputStream bis = new BufferedInputStream(is);
+		int ch;
+		while ((ch = bis.read()) != -1) {
+			result.append((char) ch);
+		}
+		bis.close();
+		return result.toString();
+	}
+
+	public Object create(Bundle bundle, String name,
+			IEclipseContext context) {
+		ContributionData cd = new ContributionData();
+		cd.bundle = bundle;
+		cd.name = name;
+		cd.context = context;
+		Object result = cd.updateContribution(js, null);
+		ContributionWrapper wrapper = new ContributionWrapper(result);
+		contributionDatas.put(wrapper, cd);
+		return wrapper;
+	}
+
+	public Object call(Object o, String methodName,
+			IEclipseContext context, Object defaultValue) {
+		ContributionWrapper wrapper = (ContributionWrapper) o;
+		ContributionData cd = (ContributionData) contributionDatas.get(wrapper);
+		wrapper.contribution = cd.updateContribution(js, wrapper.contribution);
+		Object runargs = js.get(wrapper.contribution, methodName + "args");
+		int len = js.length(runargs);
+		Object[] args = new Object[len];
+		for (int i = 0; i < len; i++) {
+			args[i] = context.get((String) js.get(runargs, i));
+		}
+		Object function = js.get(wrapper.contribution, methodName);
+
+		if (function== null || !(function instanceof Scriptable)) {
+			if (defaultValue != null) {
+				return defaultValue;
+			}
+			throw new RuntimeException(
+					"could not find function " + methodName + " in " + cd.name); //$NON-NLS-1$//$NON-NLS-2$
+		}
+
+		Object result = js.call(function,
+				wrapper.contribution, args);
+		return result;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSUtil.java b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSUtil.java
new file mode 100644
index 0000000..6ac9e68
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSUtil.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.javascript;
+
+import org.mozilla.javascript.*;
+
+public class JSUtil {
+
+	private Context jsContext;
+	private ImporterTopLevel jsScope;
+
+	public JSUtil() {
+		jsContext = Context.enter();
+		jsScope = new ImporterTopLevel(jsContext);
+	}
+
+	public Object eval(String js) {
+		Object result = jsContext.evaluateString(jsScope, "[" + js + "][0]", "eval", 0, null); //$NON-NLS-1$
+		return result;
+	}
+	
+	public Object get(Object jsObject, String attribute) {
+		if (jsObject instanceof Scriptable) {
+			return ((Scriptable) jsObject).get(attribute,
+					(IdScriptableObject) jsObject);
+		}
+		return null;
+	}
+
+	public Object get(Object jsArray, int index) {
+		return ((IdScriptableObject) jsArray).get(index,
+				(IdScriptableObject) jsArray);
+	}
+	
+	public int length(Object jsArray) {
+		Number number = (Number) get(jsArray, "length");
+		return number == null ? 0 : number.intValue();
+	}
+
+	public Object call(Object jsFunction, Object jsThis, Object[] args) {
+		return ((BaseFunction) jsFunction).call(jsContext, jsScope,
+				(Scriptable) jsThis, args);
+	}
+
+	static class Foo {
+		public int incremented(int i) {
+			return i + 1;
+		}
+	}
+
+	public static void main(String[] a) {
+		JSUtil js = new JSUtil();
+		Object result = js
+				.eval("{args:['foo','bar'], f:function(foo, x){return foo.incremented(x);}}");
+		System.out.println(result);
+		Object args = js.get(result, "args");
+		System.out.println(args);
+		System.out.println("length: " + js.length(args));
+		Object function = js.get(result, "f");
+		System.out.println(function);
+		System.out.println(js.get(args, 0));
+		System.out.println(js.get(args, 1));
+		Object fResult = js.call(function, null, new Object[] { new Foo(), 6 });
+		System.out.println(fResult);
+	}
+}
diff --git a/bundles/org.eclipse.e4.pde.ui/.classpath b/bundles/org.eclipse.e4.pde.ui/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.pde.ui/.project b/bundles/org.eclipse.e4.pde.ui/.project
new file mode 100644
index 0000000..9146e5a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.pde.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.pde.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.pde.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a3b5e6a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu Jul 09 14:42:57 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.pde.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.pde.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e22a830
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: e4 PDE UI (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.pde.ui;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.pde.webui;bundle-version="0.9.0",
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.equinox.registry;bundle-version="3.4.100",
+ org.eclipse.ui.ide;bundle-version="3.5.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.e4.ui.web;bundle-version="0.9.0"
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.pde.ui/build.properties b/bundles/org.eclipse.e4.pde.ui/build.properties
new file mode 100644
index 0000000..6c480f3
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               icons/
diff --git a/bundles/org.eclipse.e4.pde.ui/icons/obj16/site_xml_obj.gif b/bundles/org.eclipse.e4.pde.ui/icons/obj16/site_xml_obj.gif
new file mode 100644
index 0000000..35ff8c1
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/icons/obj16/site_xml_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.ui/plugin.xml b/bundles/org.eclipse.e4.pde.ui/plugin.xml
new file mode 100644
index 0000000..c29e853
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/plugin.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            class="org.eclipse.e4.pde.internal.ui.BrowserSiteEditor"
+            default="false"
+            icon="icons/obj16/site_xml_obj.gif"
+            id="org.eclipse.e4.pde.ui.siteEditor"
+            name="Site Manifest Editor (web ui-based)">
+         <contentTypeBinding contentTypeId="org.eclipse.pde.siteManifest"/>
+      </editor>
+   </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.e4.pde.ui/src/org/eclipse/e4/pde/internal/ui/BrowserSiteEditor.java b/bundles/org.eclipse.e4.pde.ui/src/org/eclipse/e4/pde/internal/ui/BrowserSiteEditor.java
new file mode 100644
index 0000000..ab3d9bc
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/src/org/eclipse/e4/pde/internal/ui/BrowserSiteEditor.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.ui;
+
+import org.eclipse.e4.pde.internal.webui.Activator;
+import org.eclipse.e4.pde.internal.webui.PDEServlet;
+import org.eclipse.e4.ui.web.BrowserEditorPart;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.WindowEvent;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+
+public class BrowserSiteEditor extends BrowserEditorPart {
+
+	public BrowserSiteEditor() {
+	}
+
+	public void init(IEditorSite site, IEditorInput input)
+			throws PartInitException {
+		setSite(site);
+		setInput(input);
+	}
+
+	protected void configureBrowser(Browser b) {
+		Browser.setCookie("org.eclipse.e4.pde.auth="
+				+ PDEServlet.getSessionId(), "http://localhost");
+		b
+				.setUrl("http://localhost:"
+						+ Activator.PORT
+						+ "/tree.html#"
+						+ ((IFileEditorInput) getEditorInput()).getFile()
+								.getFullPath());
+	}
+
+	protected IEditorInput getNewWindowEditorInput(WindowEvent event) {
+		return null;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/.classpath b/bundles/org.eclipse.e4.pde.webui/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.pde.webui/.project b/bundles/org.eclipse.e4.pde.webui/.project
new file mode 100644
index 0000000..5644051
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.pde.webui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.pde.webui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.pde.webui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a3b5e6a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu Jul 09 14:42:57 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.pde.webui/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.pde.webui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a02a109
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: PDE web ui (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.pde.webui
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.e4.pde.internal.webui.Activator
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Import-Package: org.eclipse.equinox.http.jetty;version="1.1.0",
+ org.osgi.service.http;version="1.2.1"
+Require-Bundle: org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.osgi;bundle-version="3.5.0",
+ javax.servlet;bundle-version="2.5.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.equinox.preferences;bundle-version="3.2.300",
+ org.eclipse.core.jobs;bundle-version="3.4.100",
+ org.eclipse.pde.core;bundle-version="3.5.0",
+ org.eclipse.emf.ecore;bundle-version="2.5.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.dojotoolkit;bundle-version="1.1.0"
+Export-Package: org.eclipse.e4.pde.internal.webui;x-internal:=true
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.pde.webui/build.properties b/bundles/org.eclipse.e4.pde.webui/build.properties
new file mode 100644
index 0000000..140c6e3
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               static/,\
+               model/Site.ecore
diff --git a/bundles/org.eclipse.e4.pde.webui/model/Site.ecore b/bundles/org.eclipse.e4.pde.webui/model/Site.ecore
new file mode 100644
index 0000000..c951a57
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/Site.ecore
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="site"
+    nsURI="platform:/plugin/org.eclipse.e4.pde.site.model/site.xsd" nsPrefix="org.eclipse.e4.pde.site">
+  <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+    <details key="qualified" value="false"/>
+  </eAnnotations>
+  <eClassifiers xsi:type="ecore:EClass" name="CategoryDef">
+    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+      <details key="name" value="CategoryDef"/>
+      <details key="kind" value="elementOnly"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" lowerBound="1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="description"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="label"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="name"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="CategoryType">
+    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+      <details key="name" value="category_._type"/>
+      <details key="kind" value="empty"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="name"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Description">
+    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+      <details key="name" value="Description"/>
+      <details key="kind" value="simple"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="name" value=":0"/>
+        <details key="kind" value="simple"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="url" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnyURI">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="url"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DocumentRoot">
+    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+      <details key="name" value=""/>
+      <details key="kind" value="mixed"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="mixed" unique="false" upperBound="-1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFeatureMapEntry">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="elementWildcard"/>
+        <details key="name" value=":mixed"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="xMLNSPrefixMap" upperBound="-1"
+        eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EStringToStringMapEntry"
+        transient="true" containment="true" resolveProxies="false">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="xmlns:prefix"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="xSISchemaLocation" upperBound="-1"
+        eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EStringToStringMapEntry"
+        transient="true" containment="true" resolveProxies="false">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="xsi:schemaLocation"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="site" upperBound="-2" eType="#//Site"
+        volatile="true" transient="true" derived="true" containment="true" resolveProxies="false">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="site"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Feature">
+    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+      <details key="name" value="Feature"/>
+      <details key="kind" value="elementOnly"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="category" eType="#//CategoryType"
+        containment="true" resolveProxies="false">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="category"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="id"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="url" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnyURI">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="url"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="attribute"/>
+        <details key="name" value="version"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Site">
+    <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+      <details key="name" value="Site"/>
+      <details key="kind" value="elementOnly"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="description" lowerBound="1"
+        eType="#//Description" containment="true" resolveProxies="false">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="description"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="feature" upperBound="-1"
+        eType="#//Feature" containment="true" resolveProxies="false">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="feature"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="categoryDef" upperBound="-1"
+        eType="#//CategoryDef" containment="true" resolveProxies="false">
+      <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+        <details key="kind" value="element"/>
+        <details key="name" value="category-def"/>
+        <details key="namespace" value="##targetNamespace"/>
+      </eAnnotations>
+    </eStructuralFeatures>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/bundles/org.eclipse.e4.pde.webui/model/site.genmodel b/bundles/org.eclipse.e4.pde.webui/model/site.genmodel
new file mode 100644
index 0000000..77c2494
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/site.genmodel
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.e4.pde.site.model/src"
+    modelPluginID="org.eclipse.e4.pde.site.model" modelName="Site" importerID="org.eclipse.xsd.ecore.importer"
+    complianceLevel="6.0" copyrightFields="false">
+  <foreignModel>../site.xsd</foreignModel>
+  <genPackages prefix="site" basePackage="org.eclipse.e4.pde" resource="XML" disposableProviderFactory="true"
+      ecorePackage="Site.ecore#/">
+    <genClasses ecoreClass="Site.ecore#//CategoryDef">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryDef/description"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryDef/label"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryDef/name"/>
+    </genClasses>
+    <genClasses ecoreClass="Site.ecore#//CategoryType">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryType/name"/>
+    </genClasses>
+    <genClasses ecoreClass="Site.ecore#//Description">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Description/value"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Description/url"/>
+    </genClasses>
+    <genClasses ecoreClass="Site.ecore#//DocumentRoot">
+      <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//DocumentRoot/mixed"/>
+      <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EReference Site.ecore#//DocumentRoot/xMLNSPrefixMap"/>
+      <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EReference Site.ecore#//DocumentRoot/xSISchemaLocation"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//DocumentRoot/site"/>
+    </genClasses>
+    <genClasses ecoreClass="Site.ecore#//Feature">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Feature/category"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Feature/id"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Feature/url"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Feature/version"/>
+    </genClasses>
+    <genClasses ecoreClass="Site.ecore#//Site">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Site/description"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Site/feature"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Site/categoryDef"/>
+    </genClasses>
+  </genPackages>
+</genmodel:GenModel>
diff --git a/bundles/org.eclipse.e4.pde.webui/model/site.xsd b/bundles/org.eclipse.e4.pde.webui/model/site.xsd
new file mode 100644
index 0000000..725cc75
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/site.xsd
@@ -0,0 +1,45 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+	<xsd:element name="site" type="Site" />
+
+	<xsd:complexType name="Site">
+		<xsd:sequence>
+			<xsd:element name="description" type="Description" />
+			<xsd:element name="feature" minOccurs="0" maxOccurs="unbounded"
+				type="Feature" />
+			<xsd:element name="category-def" minOccurs="0" maxOccurs="unbounded"
+				type="CategoryDef" />
+		</xsd:sequence>
+	</xsd:complexType>
+	
+	<xsd:complexType name="Description">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:string">
+				<xsd:attribute name="url" type="xsd:anyURI" />
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	
+	<xsd:complexType name="Feature">
+		<xsd:sequence>
+			<xsd:element name="category" minOccurs="0">
+				<xsd:complexType>
+					<xsd:attribute name="name" type="xsd:string" />
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:sequence>
+		<xsd:attribute name="url" type="xsd:anyURI" />
+		<xsd:attribute name="id" type="xsd:string" />
+		<xsd:attribute name="version" type="xsd:string" />
+	</xsd:complexType>
+	
+	<xsd:complexType name="CategoryDef">
+		<xsd:sequence>
+			<xsd:element name="description" minOccurs="1" maxOccurs="1"
+				type="xsd:string" />
+		</xsd:sequence>
+		<xsd:attribute name="name" type="xsd:string" />
+		<xsd:attribute name="label" type="xsd:string" />
+	</xsd:complexType>
+
+</xsd:schema>
diff --git a/bundles/org.eclipse.e4.pde.webui/model/site.xsd2ecore b/bundles/org.eclipse.e4.pde.webui/model/site.xsd2ecore
new file mode 100644
index 0000000..0a82b27
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/site.xsd2ecore
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ASCII"?>
+<xsd2ecore:XSD2EcoreMappingRoot xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsd2ecore="http://www.eclipse.org/emf/2002/XSD2Ecore" inputs="../site.xsd#/"
+    outputs="Site.ecore#/" topToBottom="true">
+  <nested inputs="bundleentry://623.fwk9489155/cache/www.w3.org/2001/XMLSchema.xsd#//string;XSDSimpleTypeDefinition=9"
+      outputs="http://www.eclipse.org/emf/2003/XMLType#//String"/>
+  <nested inputs="bundleentry://623.fwk9489155/cache/www.w3.org/2001/XMLSchema.xsd#//anyURI;XSDSimpleTypeDefinition=25"
+      outputs="http://www.eclipse.org/emf/2003/XMLType#//AnyURI"/>
+  <nested inputs="../site.xsd#//Description;XSDComplexTypeDefinition=1" outputs="Site.ecore#//Description">
+    <nested inputs="../site.xsd#//Description;XSDComplexTypeDefinition=1/XSDAttributeUse"
+        outputs="Site.ecore#//Description/url"/>
+  </nested>
+  <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDParticle/XSDModelGroup/XSDParticle/category;XSDElementDeclaration/XSDComplexTypeDefinition"
+      outputs="Site.ecore#//CategoryType">
+    <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDParticle/XSDModelGroup/XSDParticle/category;XSDElementDeclaration/XSDComplexTypeDefinition/XSDAttributeUse"
+        outputs="Site.ecore#//CategoryType/name"/>
+  </nested>
+  <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2" outputs="Site.ecore#//Feature">
+    <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDParticle/XSDModelGroup/XSDParticle"
+        outputs="Site.ecore#//Feature/category"/>
+    <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDAttributeUse=1"
+        outputs="Site.ecore#//Feature/id"/>
+    <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDAttributeUse"
+        outputs="Site.ecore#//Feature/url"/>
+    <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDAttributeUse=2"
+        outputs="Site.ecore#//Feature/version"/>
+  </nested>
+  <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3" outputs="Site.ecore#//CategoryDef">
+    <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3/XSDParticle/XSDModelGroup/XSDParticle"
+        outputs="Site.ecore#//CategoryDef/description"/>
+    <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3/XSDAttributeUse=1"
+        outputs="Site.ecore#//CategoryDef/label"/>
+    <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3/XSDAttributeUse"
+        outputs="Site.ecore#//CategoryDef/name"/>
+  </nested>
+  <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition" outputs="Site.ecore#//Site">
+    <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition/XSDParticle/XSDModelGroup/XSDParticle"
+        outputs="Site.ecore#//Site/description"/>
+    <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition/XSDParticle/XSDModelGroup/XSDParticle=1"
+        outputs="Site.ecore#//Site/feature"/>
+    <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition/XSDParticle/XSDModelGroup/XSDParticle=2"
+        outputs="Site.ecore#//Site/categoryDef"/>
+  </nested>
+  <nested inputs="../site.xsd#//site;XSDElementDeclaration" outputs="Site.ecore#//DocumentRoot/site"/>
+</xsd2ecore:XSD2EcoreMappingRoot>
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/Activator.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/Activator.java
new file mode 100644
index 0000000..d731e91
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/Activator.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * Simon Kaegi, Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.util.Hashtable;
+
+import org.eclipse.equinox.http.jetty.JettyConfigurator;
+import org.eclipse.equinox.http.jetty.JettyConstants;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.http.HttpService;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class Activator implements BundleActivator {
+
+    private ServiceTracker httpServiceTracker;
+    protected static volatile BundleContext bundleContext;
+    static boolean DEBUG;
+    {
+    	String debug = System.getProperty("org.eclipse.e4.pde.webui.debug");
+		if (debug != null && !"false".equals(debug.toLowerCase())) {
+			DEBUG = true;
+		}
+    }
+
+    public void start(BundleContext context) throws Exception {
+    	Hashtable settings = new Hashtable();
+    	
+    	if (DEBUG) {
+    		settings.put(JettyConstants.HTTP_HOST,"127.0.0.1");
+    	} else {
+    		// in non-debug mode, only accept connections from localhost:
+    		settings.put(JettyConstants.HTTP_HOST,"0.0.0.0");
+    	}
+    	
+    	settings.put(JettyConstants.HTTP_PORT,Integer.valueOf(0));
+    	settings.put(JettyConstants.OTHER_INFO, "e4.pde.webui");    	
+    	JettyConfigurator.startServer("e4.pde.webui", settings);
+    	
+    	
+        bundleContext = context;
+        Filter filter = context.createFilter("(&(" + Constants.OBJECTCLASS + "="	+ HttpService.class.getName() + ")(other.info=e4.pde.webui))");
+        httpServiceTracker = new HttpServiceTracker(context, filter);
+        httpServiceTracker.open();
+    }
+
+    public void stop(BundleContext context) throws Exception {
+        httpServiceTracker.close();
+        httpServiceTracker = null;
+        bundleContext = null;
+        JettyConfigurator.stopServer("e4.pde.webui");
+    }
+
+    public static Object PORT;
+
+    private class HttpServiceTracker extends ServiceTracker {
+
+
+		public HttpServiceTracker(BundleContext context, Filter filter) {
+        	super(context, filter, null);
+        }
+
+
+		public Object addingService(ServiceReference reference) {
+            HttpService httpService = (HttpService) super.addingService(reference); // calls context.getService(reference);
+            PORT = reference.getProperty(JettyConstants.HTTP_PORT);
+            if (DEBUG) {
+				System.out.println("listening on: " + PORT);
+            }
+            if (httpService == null)
+                return null;
+
+            HttpContext httpContext = new BundleEntryHttpContext(context.getBundle());
+            Bundle dojoBundle = getDojoBundle();
+            HttpContext dojoHttpContext = new BundleEntryHttpContext(dojoBundle);
+
+            try {
+                httpService.registerResources("/org.dojotoolkit", "/", dojoHttpContext);
+                httpService.registerResources("/", "/static", httpContext);
+                httpService.registerServlet("/pde", new PDEServlet(), null, httpContext);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return httpService;
+        }
+
+        private Bundle getDojoBundle() {
+            Bundle[] bundles = context.getBundles();
+            for (int i = 0; i < bundles.length; i++) {
+                if (bundles[i].getSymbolicName().equals("org.dojotoolkit"))
+                    return bundles[i];
+            }
+            throw new IllegalStateException("Couldn't find the 'org.dojotoolkit' bundle.");
+        }
+
+        public void removedService(ServiceReference reference, Object service) {
+            HttpService httpService = (HttpService) service;
+            httpService.unregister("/org.dojotoolkit");
+            httpService.unregister("/");
+            super.removedService(reference, service); // calls context.ungetService(reference);
+        }
+    }
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/BundleEntryHttpContext.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/BundleEntryHttpContext.java
new file mode 100644
index 0000000..6ea8d39
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/BundleEntryHttpContext.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation, Cognos Incorporated and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.osgi.framework.Bundle;
+import org.osgi.service.http.HttpContext;
+
+public class BundleEntryHttpContext implements HttpContext {
+    private Bundle bundle;
+    private String bundlePath;
+
+    public BundleEntryHttpContext(Bundle bundle) {
+        this.bundle = bundle;
+    }
+
+    public BundleEntryHttpContext(Bundle b, String bundlePath) {
+        this(b);
+        if (bundlePath != null) {
+            if (bundlePath.endsWith("/")) //$NON-NLS-1$
+                bundlePath = bundlePath.substring(0, bundlePath.length() - 1);
+
+            if (bundlePath.length() == 0)
+                bundlePath = null;
+        }
+        this.bundlePath = bundlePath;
+    }
+
+    public String getMimeType(String arg0) {
+        return null;
+    }
+
+    public boolean handleSecurity(HttpServletRequest arg0, HttpServletResponse arg1) throws IOException {
+        return true;
+    }
+
+    public URL getResource(String resourceName) {
+        if (bundlePath != null)
+            resourceName = bundlePath + resourceName;
+
+        int lastSlash = resourceName.lastIndexOf('/');
+        if (lastSlash == -1)
+            return null;
+
+        if (resourceName.endsWith("/"))
+            resourceName += "index.html";
+
+        String path = resourceName.substring(0, lastSlash);
+        if (path.length() == 0)
+            path = "/"; //$NON-NLS-1$
+        String file = resourceName.substring(lastSlash + 1);
+        Enumeration entryPaths = bundle.findEntries(path, file, false);
+
+        if (entryPaths != null && entryPaths.hasMoreElements())
+            return (URL) entryPaths.nextElement();
+
+        return null;
+    }
+
+    public Set getResourcePaths(String path) {
+        if (bundlePath != null)
+            path = bundlePath + path;
+
+        Enumeration entryPaths = bundle.findEntries(path, null, false);
+        if (entryPaths == null)
+            return null;
+
+        Set result = new HashSet();
+        while (entryPaths.hasMoreElements()) {
+            URL entryURL = (URL) entryPaths.nextElement();
+            String entryPath = entryURL.getFile();
+
+            if (bundlePath == null)
+                result.add(entryPath);
+            else
+                result.add(entryPath.substring(bundlePath.length()));
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/EMFJSONUtil.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/EMFJSONUtil.java
new file mode 100644
index 0000000..31322e7
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/EMFJSONUtil.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.math.BigDecimal;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMap.Entry;
+
+// JSON <--> Java
+//------------------
+// string <--> java.lang.String
+// number <--> java.math.Number (BigDecimal)
+// object <--> java.util.Map (HashMap)
+// array <--> java.util.Collection (ArrayList)
+// true <--> java.lang.Boolean.TRUE
+// false <--> java.lang.Boolean.FALSE
+// null <--> null
+
+public class EMFJSONUtil {
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+	private static final String NULL = "null"; //$NON-NLS-1$
+
+	public static Object read(String jsonString) {
+		return parse(new StringCharacterIterator(jsonString));
+	}
+
+	public static String write(EObject jsonObject) {
+		StringBuffer buffer = new StringBuffer();
+		writeValue(jsonObject, buffer);
+		return buffer.toString();
+	}
+
+	private static RuntimeException error(String message, CharacterIterator it) {
+		return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$
+	}
+
+	private static RuntimeException error(String message) {
+		return new IllegalStateException(message);
+	}
+
+	private static Object parse(CharacterIterator it) {
+		parseWhitespace(it);
+		Object result = parseValue(it);
+		parseWhitespace(it);
+
+		if (it.current() != CharacterIterator.DONE)
+			throw error("should be done", it); //$NON-NLS-1$
+		return result;
+	}
+
+	private static void parseWhitespace(CharacterIterator it) {
+		char c = it.current();
+		while (Character.isWhitespace(c))
+			c = it.next();
+	}
+
+	private static Object parseValue(CharacterIterator it) {
+		switch (it.current()) {
+			case '{' :
+				return parseObject(it);
+			case '[' :
+				return parseArray(it);
+			case '"' :
+				return parseString(it);
+			case '-' :
+			case '0' :
+			case '1' :
+			case '2' :
+			case '3' :
+			case '4' :
+			case '5' :
+			case '6' :
+			case '7' :
+			case '8' :
+			case '9' :
+				return parseNumber(it);
+			case 't' :
+				parseText(Boolean.TRUE.toString(), it);
+				return Boolean.TRUE;
+			case 'f' :
+				parseText(Boolean.FALSE.toString(), it);
+				return Boolean.FALSE;
+			case 'n' :
+				parseText(NULL, it);
+				return null;
+		}
+		throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+	}
+
+	private static Map parseObject(CharacterIterator it) {
+		it.next();
+		parseWhitespace(it);
+		if (it.current() == '}') {
+			it.next();
+			return Collections.EMPTY_MAP;
+		}
+
+		Map map = new HashMap();
+		while (true) {
+			if (it.current() != '"')
+				throw error("expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			String key = parseString(it);
+			if (map.containsKey(key))
+				throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$
+			parseWhitespace(it);
+			if (it.current() != ':')
+				throw error("expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			it.next();
+			parseWhitespace(it);
+			Object value = parseValue(it);
+			map.put(key, value);
+			parseWhitespace(it);
+			if (it.current() == ',') {
+				it.next();
+				parseWhitespace(it);
+				continue;
+			}
+
+			if (it.current() != '}')
+				throw error("expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			break;
+		}
+		it.next();
+		return map;
+	}
+
+	private static List parseArray(CharacterIterator it) {
+		it.next();
+		parseWhitespace(it);
+		if (it.current() == ']') {
+			it.next();
+			return Collections.EMPTY_LIST;
+		}
+
+		List list = new ArrayList();
+		while (true) {
+			Object value = parseValue(it);
+			list.add(value);
+			parseWhitespace(it);
+			if (it.current() == ',') {
+				it.next();
+				parseWhitespace(it);
+				continue;
+			}
+
+			if (it.current() != ']')
+				throw error("expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			break;
+		}
+		it.next();
+		return list;
+	}
+
+	private static void parseText(String string, CharacterIterator it) {
+		int length = string.length();
+		char c = it.current();
+		for (int i = 0; i < length; i++) {
+			if (c != string.charAt(i))
+				throw error("expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$;
+			c = it.next();
+		}
+	}
+
+	private static Object parseNumber(CharacterIterator it) {
+		StringBuffer buffer = new StringBuffer();
+		char c = it.current();
+		while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E') {
+			buffer.append(c);
+			c = it.next();
+		}
+		try {
+			return new BigDecimal(buffer.toString());
+		} catch (NumberFormatException e) {
+			throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+		}
+	}
+
+	private static String parseString(CharacterIterator it) {
+		char c = it.next();
+		if (c == '"') {
+			it.next();
+			return EMPTY_STRING;
+		}
+		StringBuffer buffer = new StringBuffer();
+		while (c != '"') {
+			if (Character.isISOControl(c))
+				throw error("illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);
+
+			if (c == '\\') {
+				c = it.next();
+				switch (c) {
+					case '"' :
+					case '\\' :
+					case '/' :
+						buffer.append(c);
+						break;
+					case 'b' :
+						buffer.append('\b');
+						break;
+					case 'f' :
+						buffer.append('\f');
+						break;
+					case 'n' :
+						buffer.append('\n');
+						break;
+					case 'r' :
+						buffer.append('\r');
+						break;
+					case 't' :
+						buffer.append('\t');
+						break;
+					case 'u' :
+						StringBuffer unicode = new StringBuffer(4);
+						for (int i = 0; i < 4; i++) {
+							unicode.append(it.next());
+						}
+						try {
+							buffer.append((char) Integer.parseInt(unicode.toString(), 16));
+						} catch (NumberFormatException e) {
+							throw error("expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+						}
+						break;
+					default :
+						throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+				}
+			} else
+				buffer.append(c);
+
+			c = it.next();
+		}
+		c = it.next();
+		return buffer.toString();
+	}
+
+	private static void writeValue(Object value, StringBuffer buffer) {
+		if (value == null)
+			buffer.append(NULL);
+		else if (value instanceof Boolean || value instanceof Number)
+			buffer.append(value.toString());
+		else if (value instanceof String)
+			writeString((String) value, buffer);
+		else if (value instanceof FeatureMap)
+			writeFeatureMap((FeatureMap) value, buffer);
+		else if (value instanceof EObject)
+			writeObject((EObject) value, buffer);
+		else if (value instanceof Map)
+			writeMap((Map) value, buffer);
+		else if (value instanceof Collection)
+			writeArray((Collection) value, buffer);
+		else
+			throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+	}
+
+	private static void writeObject(EObject eObject, StringBuffer buffer) {
+		buffer.append('{');
+		for (Iterator iterator = eObject.eClass().getEAllStructuralFeatures().iterator(); iterator.hasNext();) {
+			EStructuralFeature feature = (EStructuralFeature) iterator.next();
+			writeString(feature.getName(), buffer);
+			buffer.append(':');
+			writeValue(eObject.eGet(feature), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, '}');
+		else
+			buffer.append('}');
+	}
+
+	private static void writeFeatureMap(FeatureMap featureMap, StringBuffer buffer) {
+		buffer.append('{');
+		for (Iterator iterator = featureMap.iterator(); iterator.hasNext();) {
+			FeatureMap.Entry entry = (Entry) iterator.next();
+			writeString(entry.getEStructuralFeature().getName(), buffer);
+			buffer.append(':');
+			writeValue(entry.getValue(), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, '}');
+		else
+			buffer.append('}');
+	}
+	
+	private static void writeMap(Map map, StringBuffer buffer) {
+		buffer.append('{');
+		for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
+			Object key = iterator.next();
+			if (!(key instanceof String))
+				throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+			writeString((String) key, buffer);
+			buffer.append(':');
+			writeValue(map.get(key), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, '}');
+		else
+			buffer.append('}');
+	}
+
+	private static void writeArray(Collection collection, StringBuffer buffer) {
+		buffer.append('[');
+		for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+			writeValue(iterator.next(), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, ']');
+		else
+			buffer.append(']');
+	}
+
+	private static void writeString(String string, StringBuffer buffer) {
+		buffer.append('"');
+		int length = string.length();
+		for (int i = 0; i < length; i++) {
+			char c = string.charAt(i);
+			switch (c) {
+				case '"' :
+				case '\\' :
+				case '/' :
+					buffer.append('\\');
+					buffer.append(c);
+					break;
+				case '\b' :
+					buffer.append("\\b"); //$NON-NLS-1$
+					break;
+				case '\f' :
+					buffer.append("\\f"); //$NON-NLS-1$
+					break;
+				case '\n' :
+					buffer.append("\\n"); //$NON-NLS-1$
+					break;
+				case '\r' :
+					buffer.append("\\r"); //$NON-NLS-1$
+					break;
+				case '\t' :
+					buffer.append("\\t"); //$NON-NLS-1$
+					break;
+				default :
+					if (Character.isISOControl(c)) {
+						buffer.append("\\u"); //$NON-NLS-1$
+						String hexString = Integer.toHexString(c);
+						for (int j = hexString.length(); j < 4; j++)
+							buffer.append('0');
+						buffer.append(hexString);
+					} else
+						buffer.append(c);
+			}
+		}
+		buffer.append('"');
+	}
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/JSONUtil.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/JSONUtil.java
new file mode 100644
index 0000000..3dec041
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/JSONUtil.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.math.BigDecimal;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.*;
+
+// JSON <--> Java
+//------------------
+// string <--> java.lang.String
+// number <--> java.math.Number (BigDecimal)
+// object <--> java.util.Map (HashMap)
+// array <--> java.util.Collection (ArrayList)
+// true <--> java.lang.Boolean.TRUE
+// false <--> java.lang.Boolean.FALSE
+// null <--> null
+
+public class JSONUtil {
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+	private static final String NULL = "null"; //$NON-NLS-1$
+
+	public static Object read(String jsonString) {
+		return parse(new StringCharacterIterator(jsonString));
+	}
+
+	public static String write(Object jsonObject) {
+		StringBuffer buffer = new StringBuffer();
+		writeValue(jsonObject, buffer);
+		return buffer.toString();
+	}
+
+	private static RuntimeException error(String message, CharacterIterator it) {
+		return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$
+	}
+
+	private static RuntimeException error(String message) {
+		return new IllegalStateException(message);
+	}
+
+	private static Object parse(CharacterIterator it) {
+		parseWhitespace(it);
+		Object result = parseValue(it);
+		parseWhitespace(it);
+
+		if (it.current() != CharacterIterator.DONE)
+			throw error("should be done", it); //$NON-NLS-1$
+		return result;
+	}
+
+	private static void parseWhitespace(CharacterIterator it) {
+		char c = it.current();
+		while (Character.isWhitespace(c))
+			c = it.next();
+	}
+
+	private static Object parseValue(CharacterIterator it) {
+		switch (it.current()) {
+			case '{' :
+				return parseObject(it);
+			case '[' :
+				return parseArray(it);
+			case '"' :
+				return parseString(it);
+			case '-' :
+			case '0' :
+			case '1' :
+			case '2' :
+			case '3' :
+			case '4' :
+			case '5' :
+			case '6' :
+			case '7' :
+			case '8' :
+			case '9' :
+				return parseNumber(it);
+			case 't' :
+				parseText(Boolean.TRUE.toString(), it);
+				return Boolean.TRUE;
+			case 'f' :
+				parseText(Boolean.FALSE.toString(), it);
+				return Boolean.FALSE;
+			case 'n' :
+				parseText(NULL, it);
+				return null;
+		}
+		throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+	}
+
+	private static Map parseObject(CharacterIterator it) {
+		it.next();
+		parseWhitespace(it);
+		if (it.current() == '}') {
+			it.next();
+			return Collections.EMPTY_MAP;
+		}
+
+		Map map = new HashMap();
+		while (true) {
+			if (it.current() != '"')
+				throw error("expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			String key = parseString(it);
+			if (map.containsKey(key))
+				throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$
+			parseWhitespace(it);
+			if (it.current() != ':')
+				throw error("expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			it.next();
+			parseWhitespace(it);
+			Object value = parseValue(it);
+			map.put(key, value);
+			parseWhitespace(it);
+			if (it.current() == ',') {
+				it.next();
+				parseWhitespace(it);
+				continue;
+			}
+
+			if (it.current() != '}')
+				throw error("expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			break;
+		}
+		it.next();
+		return map;
+	}
+
+	private static List parseArray(CharacterIterator it) {
+		it.next();
+		parseWhitespace(it);
+		if (it.current() == ']') {
+			it.next();
+			return Collections.EMPTY_LIST;
+		}
+
+		List list = new ArrayList();
+		while (true) {
+			Object value = parseValue(it);
+			list.add(value);
+			parseWhitespace(it);
+			if (it.current() == ',') {
+				it.next();
+				parseWhitespace(it);
+				continue;
+			}
+
+			if (it.current() != ']')
+				throw error("expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			break;
+		}
+		it.next();
+		return list;
+	}
+
+	private static void parseText(String string, CharacterIterator it) {
+		int length = string.length();
+		char c = it.current();
+		for (int i = 0; i < length; i++) {
+			if (c != string.charAt(i))
+				throw error("expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$;
+			c = it.next();
+		}
+	}
+
+	private static Object parseNumber(CharacterIterator it) {
+		StringBuffer buffer = new StringBuffer();
+		char c = it.current();
+		while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E') {
+			buffer.append(c);
+			c = it.next();
+		}
+		try {
+			return new BigDecimal(buffer.toString());
+		} catch (NumberFormatException e) {
+			throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+		}
+	}
+
+	private static String parseString(CharacterIterator it) {
+		char c = it.next();
+		if (c == '"') {
+			it.next();
+			return EMPTY_STRING;
+		}
+		StringBuffer buffer = new StringBuffer();
+		while (c != '"') {
+			if (Character.isISOControl(c))
+				throw error("illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);
+
+			if (c == '\\') {
+				c = it.next();
+				switch (c) {
+					case '"' :
+					case '\\' :
+					case '/' :
+						buffer.append(c);
+						break;
+					case 'b' :
+						buffer.append('\b');
+						break;
+					case 'f' :
+						buffer.append('\f');
+						break;
+					case 'n' :
+						buffer.append('\n');
+						break;
+					case 'r' :
+						buffer.append('\r');
+						break;
+					case 't' :
+						buffer.append('\t');
+						break;
+					case 'u' :
+						StringBuffer unicode = new StringBuffer(4);
+						for (int i = 0; i < 4; i++) {
+							unicode.append(it.next());
+						}
+						try {
+							buffer.append((char) Integer.parseInt(unicode.toString(), 16));
+						} catch (NumberFormatException e) {
+							throw error("expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+						}
+						break;
+					default :
+						throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+				}
+			} else
+				buffer.append(c);
+
+			c = it.next();
+		}
+		c = it.next();
+		return buffer.toString();
+	}
+
+	private static void writeValue(Object value, StringBuffer buffer) {
+		if (value == null)
+			buffer.append(NULL);
+		else if (value instanceof Boolean || value instanceof Number)
+			buffer.append(value.toString());
+		else if (value instanceof String)
+			writeString((String) value, buffer);
+		else if (value instanceof Collection)
+			writeArray((Collection) value, buffer);
+		else if (value instanceof Map)
+			writeObject((Map) value, buffer);
+		else
+			throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+	}
+
+	private static void writeObject(Map map, StringBuffer buffer) {
+		buffer.append('{');
+		for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
+			Object key = iterator.next();
+			if (!(key instanceof String))
+				throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+			writeString((String) key, buffer);
+			buffer.append(':');
+			writeValue(map.get(key), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, '}');
+		else
+			buffer.append('}');
+	}
+
+	private static void writeArray(Collection collection, StringBuffer buffer) {
+		buffer.append('[');
+		for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+			writeValue(iterator.next(), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, ']');
+		else
+			buffer.append(']');
+	}
+
+	private static void writeString(String string, StringBuffer buffer) {
+		buffer.append('"');
+		int length = string.length();
+		for (int i = 0; i < length; i++) {
+			char c = string.charAt(i);
+			switch (c) {
+				case '"' :
+				case '\\' :
+				case '/' :
+					buffer.append('\\');
+					buffer.append(c);
+					break;
+				case '\b' :
+					buffer.append("\\b"); //$NON-NLS-1$
+					break;
+				case '\f' :
+					buffer.append("\\f"); //$NON-NLS-1$
+					break;
+				case '\n' :
+					buffer.append("\\n"); //$NON-NLS-1$
+					break;
+				case '\r' :
+					buffer.append("\\r"); //$NON-NLS-1$
+					break;
+				case '\t' :
+					buffer.append("\\t"); //$NON-NLS-1$
+					break;
+				default :
+					if (Character.isISOControl(c)) {
+						buffer.append("\\u"); //$NON-NLS-1$
+						String hexString = Integer.toHexString(c);
+						for (int j = hexString.length(); j < 4; j++)
+							buffer.append('0');
+						buffer.append(hexString);
+					} else
+						buffer.append(c);
+			}
+		}
+		buffer.append('"');
+	}
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/PDEServlet.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/PDEServlet.java
new file mode 100644
index 0000000..86e6af0
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/PDEServlet.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.Map.Entry;
+import javax.servlet.ServletException;
+import javax.servlet.http.*;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.*;
+import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
+import org.eclipse.emf.ecore.resource.*;
+import org.eclipse.emf.ecore.resource.Resource.Factory;
+import org.eclipse.emf.ecore.resource.impl.ResourceFactoryImpl;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
+import org.eclipse.pde.internal.core.PDECore;
+import org.eclipse.pde.internal.core.ifeature.IFeature;
+import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
+import org.osgi.framework.Version;
+
+public class PDEServlet extends HttpServlet {
+
+	private static final long serialVersionUID = -5263759597889185038L;
+
+	private IWorkspace workspace;
+
+	private static String sessionID;
+
+	private synchronized IWorkspace getWorkspace() {
+		if (workspace == null) {
+			// enable auto-refresh:
+			new InstanceScope().getNode(ResourcesPlugin.PI_RESOURCES)
+					.putBoolean(ResourcesPlugin.PREF_AUTO_REFRESH, true);
+			workspace = ResourcesPlugin.getWorkspace();
+		}
+		return workspace;
+	}
+
+	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		if (!isAuthenticated(req)) {
+			resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
+			return;
+		}
+		String pathInfo = req.getPathInfo();
+		if (pathInfo.startsWith("/site/")) {
+				String wsPath = pathInfo.substring("/site".length());
+				IResource resource = getWorkspace().getRoot().findMember(
+						new Path(wsPath));
+				if (resource.getType() != IResource.FILE) {
+					resp.setStatus(405);
+					return;
+				}
+				InputStream is = req.getInputStream(); 
+				int BUFFER_SIZE = 8192;
+				byte[] buffer = new byte[BUFFER_SIZE];
+				ByteArrayOutputStream os = new ByteArrayOutputStream();
+				int numRead = 0;
+				while ((numRead = is.read(buffer)) > 0) {
+					os.write(buffer, 0, numRead);
+				}
+				String jsonString = new String(os.toByteArray(), "ISO-8859-1");
+				Object json = JSONUtil.read(jsonString);
+//				System.out.println(json);
+				URI siteEcoreURI = URI.createPlatformPluginURI("/org.eclipse.e4.pde.webui/model/Site.ecore", true);
+				ResourceSet resourceSet = createResourceSet(siteEcoreURI);
+				EPackage ePackage = resourceSet.getPackageRegistry().getEPackage("platform:/plugin/org.eclipse.e4.pde.site.model/site.xsd");
+
+				Resource.Factory factory = (Factory) resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().get(Resource.Factory.Registry.DEFAULT_EXTENSION);
+				URI uri = URI.createPlatformResourceURI(resource.getFullPath()
+						.toString(), true);
+				Resource r = factory.createResource(uri);
+				
+				EClass documentRootClass = (EClass) ePackage.getEClassifier("DocumentRoot");
+				EObject documentRoot = ePackage.getEFactoryInstance().create(documentRootClass);
+				EClass siteClass = (EClass) ePackage.getEClassifier("Site");
+				EObject site = ePackage.getEFactoryInstance().create(siteClass);
+				fill(site, (HashMap) json, ePackage.getEFactoryInstance());
+				documentRoot.eSet(documentRootClass.getEStructuralFeature("site"), site);
+				r.getContents().add(documentRoot);
+				
+				OutputStream outputStream = resourceSet.getURIConverter().createOutputStream(uri);
+				r.save(outputStream, new HashMap());
+				outputStream.close();
+		}
+	}
+	
+	private void fill(EObject eObject, HashMap json, EFactory eFactory) {
+		for(Iterator it = json.entrySet().iterator(); it.hasNext(); ) {
+			Entry entry = (Entry) it.next();
+			EStructuralFeature feature = eObject.eClass().getEStructuralFeature((String) entry.getKey());
+			if (entry.getValue() instanceof Collection) {
+				Collection targetCollection = (Collection) eObject.eGet(feature);
+				Collection sourceCollection = (Collection) entry.getValue();
+				for (Iterator it2 = sourceCollection.iterator(); it2
+						.hasNext();) {
+					Object element = it2.next();
+					EClass elementClass = (EClass) feature.getEType();
+					EObject targetElement = eFactory.create(elementClass);
+					fill(targetElement, (HashMap) element, eFactory);
+					targetCollection.add(targetElement);
+				}
+			} else if (entry.getValue() instanceof Map) {
+				EClass elementClass = (EClass) feature.getEType();
+				EObject targetElement = eFactory.create(elementClass);
+				fill(targetElement, (HashMap) entry.getValue(), eFactory);
+				eObject.eSet(feature, targetElement);
+			} else if (entry.getValue() instanceof String) {
+				eObject.eSet(feature, entry.getValue());
+			} else if (entry.getValue() != null) {
+				throw new RuntimeException("unsupported: " + entry.getValue());
+			}
+		}
+	}
+
+	protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
+		String pathInfo = req.getPathInfo();
+		if (pathInfo.startsWith("/login")) {
+			if ("e4".equals(req.getParameter("username"))) {
+				if ("e4".equals(req.getParameter("password"))) {
+					resp.addCookie(new Cookie("org.eclipse.e4.pde.auth", getSessionId()));
+					try {
+						resp.sendRedirect(req.getParameter("nextURL"));
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+					return;
+				}
+			}
+		}
+		try {
+			resp.sendRedirect("/pde/login?nextURL=" + URLEncoder.encode(req.getParameter("nextURL"), "UTF-8"));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+			throws ServletException, IOException {
+		String pathInfo = req.getPathInfo();
+		if (pathInfo.startsWith("/login")) {
+			resp.setStatus(HttpServletResponse.SC_OK);
+			resp.setContentType("text/html; charset=UTF-8");
+			PrintWriter writer = resp.getWriter();
+			writer.append("<html>");
+			writer.append("<head>");
+			writer.append("<title>Please Log In</title>");
+			writer.append("</head>");
+			writer.append("<body>");
+			writer.append("<form method='post' action='/pde/login'>");
+			writer.append("username: ");
+			writer.append("<input type='text' name='username' />");
+			writer.append("<br />");
+			writer.append("password: ");
+			writer.append("<input type='password' name='password' />");
+			writer.append("<br />");
+			writer.append("<input type='submit' value='Login' />");
+			writer.append("<input type='hidden' name='nextURL' value='" + req.getParameter("nextURL") + "' />");
+			writer.append("</form>");
+			if (Activator.DEBUG) {
+				writer.append("<script type='text/javascript' src='/listCookies.js'></script>");
+			}
+			writer.append("</body>");
+			writer.append("</html>");
+			return;
+		}
+		if (!isAuthenticated(req)) {
+			resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
+			return;
+		}
+		if (pathInfo.startsWith("/features/")) {
+			IFeatureModel[] allModels = PDECore.getDefault().getFeatureModelManager().getModels();
+			Arrays.sort(allModels, new Comparator() {
+				public int compare(Object arg0, Object arg1) {
+					IFeature f0 = ((IFeatureModel)arg0).getFeature();
+					IFeature f1 = ((IFeatureModel)arg1).getFeature();
+					return f0.getId().compareTo(f1.getId());
+				}
+			});
+			List features = new ArrayList(allModels.length);
+			for (int i = 0; i < allModels.length; i++) {
+				IFeature feature = allModels[i].getFeature();
+				Map featureJSON = new HashMap();
+				featureJSON.put("feature", null);
+				featureJSON.put("id", feature.getId());
+				featureJSON.put("url", "features/" + feature.getId() + "_" + new Version(feature.getVersion()).toString() + ".jar");
+				featureJSON.put("version", feature.getVersion());
+				features.add(featureJSON);
+			}
+			resp.setStatus(200);
+			resp.setContentType("application/json; charset=UTF-8");
+			Map jsonResult = new HashMap();
+			jsonResult.put("identifier", "id");
+			jsonResult.put("label", "id");
+			jsonResult.put("items", features);
+			PrintWriter writer = resp.getWriter();
+			writer.write("/*");
+			writer.write(JSONUtil.write(jsonResult));
+			writer.write("*/");
+			return;
+		} else if (pathInfo.startsWith("/site/")) {
+			String wsPath = pathInfo.substring("/site".length());
+			IResource resource = getWorkspace().getRoot().findMember(
+					new Path(wsPath));
+			if (resource.getType() != IResource.FILE) {
+				resp.setStatus(405);
+				return;
+			}
+			PrintWriter writer = resp.getWriter();
+			try {
+				URI siteEcoreURI = URI.createPlatformPluginURI("/org.eclipse.e4.pde.webui/model/Site.ecore", true);
+				ResourceSet resourceSet = createResourceSet(siteEcoreURI);
+
+				URI uri = URI.createPlatformResourceURI(resource.getFullPath()
+						.toString(), true);
+				Resource r = resourceSet.getResource(uri, true);
+				EObject eRootObject = (EObject) r.getContents().get(0);
+				resp.setStatus(200);
+				resp.setContentType("application/json; charset=UTF-8");
+				writer.write("/*");
+				writer.write(EMFJSONUtil.write((EObject) eRootObject.eContents().get(0)));
+				writer.write("*/");
+				return;
+			} catch (Exception e) {
+				e.printStackTrace(writer);
+				resp.setStatus(500);
+				return;
+			}
+		}
+	}
+
+	private boolean isAuthenticated(HttpServletRequest req) {
+		Cookie[] cookies = req.getCookies();
+		if (cookies != null) {
+			for (int i = 0; i < cookies.length; i++) {
+				if (cookies[i].getName().equals("org.eclipse.e4.pde.auth")) {
+					if (cookies[i].getValue().equals(getSessionId())) {
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	public static String getSessionId() {
+		if (sessionID == null) {
+			sessionID = UUID.randomUUID().toString();
+		}
+		return sessionID;
+	}
+
+	private ResourceSet createResourceSet(URI siteEcoreURI) {
+		ResourceSet resourceSet = new ResourceSetImpl();
+		Resource ecoreResource = resourceSet.getResource(siteEcoreURI, true);
+		
+		final BasicExtendedMetaData extendedMetaData = new BasicExtendedMetaData(new EPackageRegistryImpl(EPackage.Registry.INSTANCE));
+		EPackage ecorePackage = (EPackage) ecoreResource.getContents().get(0);
+		extendedMetaData.putPackage(null, ecorePackage);
+		
+		// Register the appropriate resource factory to handle all file extensions.
+		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
+			(Resource.Factory.Registry.DEFAULT_EXTENSION, 
+			 new ResourceFactoryImpl(){
+				public Resource createResource(URI uri) {
+					XMLResource result = new XMLResourceImpl(uri);
+					result.getDefaultSaveOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
+					result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
+
+					result.getDefaultSaveOptions().put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
+
+					result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
+					result.getDefaultSaveOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
+
+					result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE);
+					return result;
+				}
+			});
+		// Register the package to ensure it is available during loading.
+		//
+		resourceSet.getPackageRegistry().put
+			(ecorePackage.getNsURI(), ecorePackage);
+		return resourceSet;
+	}
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/category_obj.gif b/bundles/org.eclipse.e4.pde.webui/static/images/category_obj.gif
new file mode 100644
index 0000000..5ef0ed7
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/category_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/feature_obj.gif b/bundles/org.eclipse.e4.pde.webui/static/images/feature_obj.gif
new file mode 100644
index 0000000..411a32a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/feature_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/header-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/header-top.png
new file mode 100644
index 0000000..496a4d1
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/header-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/section-left-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/section-left-top.png
new file mode 100644
index 0000000..abe7645
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/section-left-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/section-middle-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/section-middle-top.png
new file mode 100644
index 0000000..af2d6b0
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/section-middle-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/section-right-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/section-right-top.png
new file mode 100644
index 0000000..a8b68e5
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/section-right-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/listCookies.js b/bundles/org.eclipse.e4.pde.webui/static/listCookies.js
new file mode 100644
index 0000000..017a9be
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/listCookies.js
@@ -0,0 +1,7 @@
+var cookies = document.cookie.split("; ");
+//alert("cookies");
+for (var i = 0; i < cookies.length; i++) {
+	//alert(cookies[i]);
+	document.write(cookies[i]);
+	document.write("<br/>");
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.css b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.css
new file mode 100644
index 0000000..d7c5e66
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.css
@@ -0,0 +1,8 @@
+html, body {
+	margin: 0;
+	padding: 0;
+}
+
+iframe {
+	border: none;
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.html b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.html
new file mode 100644
index 0000000..e503bb2
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.html
@@ -0,0 +1,26 @@
+<!--*****************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ ******************************************************************************-->
+<html>
+<head>
+<title>Site Manifest Editor</title>
+	<style type="text/css">
+	    @import "tree-standalone.css";
+	</style>
+</head>
+<body>
+<iframe frameborder="0" id="editor" width="100%" height="100%"></iframe>
+<script type="text/javascript">
+  var hash = window.document.location.hash;
+  var editor = document.getElementById("editor");
+  editor.src = "/tree.html" + hash; 
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree.css b/bundles/org.eclipse.e4.pde.webui/static/tree.css
new file mode 100644
index 0000000..ce97b2d
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree.css
@@ -0,0 +1,154 @@
+html {
+  overflow-x: hidden; // hack to get rid of horizontal scrollbar
+}
+
+html, body {
+	margin: 0;
+	padding: 0;
+	font-size: 12px;
+}
+
+#header {
+    margin: 0;
+	width: 100%;
+	height: 36px;
+	background: url(images/header-top.png) 0 0 repeat-x;
+    padding-left: 5px;
+    padding-top: 5px;
+}
+
+#saveButton {
+	margin-right: 10px;
+	width: 80px;
+	float: right;
+	visibility: hidden;
+}
+
+#saveButton input {
+	width: 100%;
+	font-weight:bold;
+	color: #316ac5;
+}
+
+h1 {
+	font-size:1.5em;
+	font-weight:bold;
+	color: #316ac5;
+	line-height: 36px;
+	position:absolute;
+	top:0;
+	bottom:0;
+	margin:auto;
+}
+
+h2 {
+	font-size: 1.1em;
+	font-weight: bold;
+	color: #316ac5;
+	margin: 0;
+}
+
+.pane {
+    margin: 10px;
+}
+
+.sectionTop, .sectionTop2 {
+    background: url(images/section-middle-top.png) 0 0 repeat-x;
+}
+
+.sectionTL {
+    background: url(images/section-left-top.png) 0 0 no-repeat;
+}
+
+.sectionTR {
+    background: url(images/section-right-top.png) 100% 0 no-repeat;
+    padding-left: 5px;
+    padding-top: 3px;
+}
+
+.sectionTop2 {
+	margin-top: 2em;
+}
+
+.soria .dijitSplitterV .dijitSplitterThumb {
+	background: #FFFFFF;
+}
+
+.soria .dijitSplitterV {
+	background: #FFFFFF;
+}
+
+#tree {
+	margin-right: 9em;
+	overflow-x: hidden;
+}
+
+#treeButtons br {
+	line-height: 0.5em;
+}
+
+#treeButtons {
+	margin: 0;
+	padding: 0;
+	float: right;
+	width: 9em;
+}
+
+#treeButtons .contentButton {
+	width: 8.5em;
+	margin: 0;
+	margin-bottom: 3px;
+	font-size: 1em;
+}
+
+.categoryItem {
+	background: url(images/category_obj.gif);
+}
+
+.featureItem {
+	background: url(images/feature_obj.gif);
+}
+
+#categoryProperties {
+	display: none;
+}
+
+#featureProperties {
+	display: none;
+}
+
+.fieldLabel {
+	color: #316ac5;
+	width: 6em;
+	float: left;
+	margin-top: 4px;
+}
+
+.fieldText {
+	margin-left: 6em;
+	padding: 2px;
+}
+
+.longfieldLabel {
+	color: #316ac5;
+	width: 9.5em;
+	float: left;
+	margin-top: 4px;
+}
+
+.longfieldText {
+	margin-left: 9.5em;
+	padding: 2px;
+}
+
+.fieldText input {
+	width: 100%;
+}
+
+.longfieldText input {
+	width: 100%;
+}
+
+.fieldText textarea {
+	width: 100%;
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree.html b/bundles/org.eclipse.e4.pde.webui/static/tree.html
new file mode 100644
index 0000000..a818796
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree.html
@@ -0,0 +1,97 @@
+<!--*****************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ ******************************************************************************-->
+<html>
+    <head>
+    	<title>Update Site Map</title>    
+    
+    <script type="text/javascript">
+        var djConfig = {
+		    isDebug:false,
+		    parseOnLoad:true
+        };
+    </script>
+    <script type="text/javascript" src="/org.dojotoolkit/dojo/dojo.js.uncompressed.js"></script>
+    	
+	<style type="text/css">
+		@import "/org.dojotoolkit/dojo/resources/dojo.css";
+		@import "/org.dojotoolkit/dijit/themes/soria/soria.css";
+		@import "/org.dojotoolkit/dijit/themes/soria/Tree.css";
+		@import "/org.dojotoolkit/dijit/themes/soria/layout/BorderContainer.css";
+		@import "/org.dojotoolkit/dijit/themes/soria/form/Common.css";
+		@import "/org.dojotoolkit/dijit/themes/soria/form/Button.css";
+	    @import "tree.css";
+	</style>
+
+    </head>
+
+    <body class="soria">
+    <script type="text/javascript" src="tree.js"></script>
+    
+    <div id="header"><h1>Update Site Map<span style="visibility:hidden;" id="dirtyIndicator">*</span></h1><div id="saveButton"><input type="button" value="Save" /></div></div>
+    
+    <div dojoType="dijit.layout.BorderContainer" design="sidebar" liveSplitters="false" gutters="false" style="width: 100%; height: 90%;">
+		<div class="pane" id="leftPane" dojoType="dijit.layout.ContentPane" region="center">
+			<div class="sectionTop"><div class="sectionTL"><div class="sectionTR">
+		        <h2>Managing the Site</h2>
+		        <ol>
+			        <li>Add the features to be published on the site.</li>
+			        <li>For easier browsing of the site, categorize the features by dragging.</li>
+			        <li>Build the features.</li>
+		        </ol>
+		        <div id="treeButtons">
+			        <button class="contentButton" id="newCategory">New Category</button><br/>
+			        <button class="contentButton" id="addFeature">Add Feature...</button><br/><br/>
+			        <button class="contentButton" id="synchronize">Synchronize...</button><br/><br/>
+			        <button class="contentButton" id="build">Build</button><br/>
+			        <button class="contentButton" id="buildAll">Build All</button><br/>
+		        </div>
+				<div id="tree"></div>
+			</div></div></div>
+		</div>
+		<div class="pane" id="rightPane" dojoType="dijit.layout.ContentPane" region="trailing" style="width: 50%;" splitter="true">
+			<div id="categoryProperties">
+			<div class="sectionTop"><div class="sectionTL"><div class="sectionTR">
+	        	<h2>Category Properties</h2>
+	        	Provide a unique id, a name and a description for each category.<br/>
+				"*" denotes a required field.<br/>
+		        <div class="fieldLabel">ID*:</div><div class="fieldText"><input type="text" id="categoryID""/></div>
+		        <div class="fieldLabel">Name*:</div><div class="fieldText"><input type="text" id="categoryName""/></div>
+		        <div class="fieldLabel">Description:</div><div class="fieldText"><textarea id="categoryDescription"></textarea></div>
+			</div></div></div>
+			</div>
+			<div id="featureProperties">
+			<div class="sectionTop"><div class="sectionTL"><div class="sectionTR">
+	        	<h2>Feature Properties</h2>
+	        	Properties for the selected feature.  "*" denotes a required field.<br/>
+		        <div class="fieldLabel">ID*:</div><div class="fieldText"><input type="text" id="featureID""/></div>
+		        <div class="fieldLabel">Version:</div><div class="fieldText"><input type="text" id="featureVersion""/></div>
+		        <div class="fieldLabel">URL*:</div><div class="fieldText"><input type="text" id="featureURL""/></div>
+		        <input type="checkbox"/ id="featureIsPatch"> This feature is a patch for another feature
+			</div></div></div>
+			<div class="sectionTop2"><div class="sectionTL"><div class="sectionTR">
+	        	<h2>Feature Environments</h2>
+	        	Specify the environments in which this feature can be installed.<br/>
+				Leave blank if the feature does not contain platform-specific code.<br/>
+		        <div class="longfieldLabel">Operating Systems:</div><div class="longfieldText"><input type="text" id="featureOS""/></div>
+		        <div class="longfieldLabel">Window Systems:</div><div class="longfieldText"><input type="text" id="featureWS""/></div>
+		        <div class="longfieldLabel">Languages:</div><div class="longfieldText"><input type="text" id="featureLanguages""/></div>
+		        <div class="longfieldLabel">Architecture:</div><div class="longfieldText"><input type="text" id="featureArchitecture""/></div>
+			</div></div></div>
+			</div>
+		</div>
+	</div>
+	<div dojoType="dijit.Dialog" id="featureDialog" title="Dialog Test">
+		Select a feature:<br/>
+		<input id="featureSelect"></input>
+		<input id="featureSelectOK" type="submit" dojoType="dijit.form.Button" value="OK">OK</input> 
+	</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree.js b/bundles/org.eclipse.e4.pde.webui/static/tree.js
new file mode 100644
index 0000000..cd978fb
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree.js
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+var dirty = false;
+
+window.e4 = window.e4 || {
+	status : {
+		setMessage : function(msg) { alert(msg); },
+		setDirty : function(d) {
+			dirty = d;
+			dojo.byId("dirtyIndicator").style.visibility = d ? "visible" : "hidden";
+			dojo.byId("saveButton").style.visibility = d ? "visible" : "hidden";
+		}
+	},
+	
+	saveable : {
+		doSave : function(callback) {}
+	}
+};
+
+treeRoot = {categories:{}, children:[]};
+
+function doSave() {
+	var jsonData = {categoryDef: [], feature: []};
+	for (var i in treeRoot.children) {
+	  var child = treeRoot.children[i];
+	  if (child.id) {
+	    // child is a feature
+	    jsonData.feature.push(child);
+	  } else {
+	    // child is a category
+	    var category = { name: child.name, label: child.label, description: child.label};
+	    jsonData.categoryDef.push(category);
+	    for (var j in child.children) {
+	      var feature = child.children[j];
+	      feature.category = {name: child.name};
+	      jsonData.feature.push(feature);
+	    }
+	  }
+	}
+	var jsonString = dojo.toJson(jsonData);
+	//alert(jsonString);
+	dojo.rawXhrPut({
+        url: "/pde/site" + dojo.doc.location.hash.substring(1), 
+        putData: jsonString,
+        timeout: 5000,
+        load: function(response, ioArgs) {
+        	//alert("success: " + response + ", " + ioArgs);
+			window.e4.status.setDirty(false);
+        	return response;
+        },
+        error: function(response, ioArgs) {
+        	alert("ERROR: " + response + ", " + ioArgs);
+        	return response;
+        }
+	});
+}
+
+dojo.require("dijit.dijit");
+dojo.require("dijit.Dialog");
+dojo.require("dijit.Tree");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.FilteringSelect");
+dojo.require("dijit.layout.BorderContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dojo.cookie");
+
+var modelPrototype = {
+	destroy: function(){
+	},
+	
+	getRoot: function(onItem){
+		onItem(this.root);
+	},
+	
+	mayHaveChildren: function(/*dojo.data.Item*/ item){
+	    var result = item.children != undefined;
+		return result;
+	},
+	
+	getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete){
+	  if (parentItem.children) {
+	    onComplete(parentItem.children);
+	  } else {
+	    onComplete([]);
+	  }
+	},
+	
+	getIdentity: function(/* item */ item){
+		var result = item.id;
+		if (item === this.root) {
+		  result = "ROOT";
+		}
+		if (!result) {
+		  result = item.name;
+		}	
+		return result;
+	},
+	
+	getLabel: function(/*dojo.data.Item*/ item){
+		return item.id || item.name;
+	},
+	
+	newItem: function(/* Object? */ args, /*Item?*/ parent){
+	},
+	
+	pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy){
+	},
+		
+	onChange: function(/*dojo.data.Item*/ item){
+		window.e4.status.setDirty(true);
+	},
+	
+	onChildrenChange: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+		window.e4.status.setDirty(true);
+	}
+};
+
+window.onbeforeunload = function (evt) {
+  var message = "You have unsaved changes.";
+  if (dirty) {
+	  return message;
+  }
+};
+dojo.addOnLoad(function(){
+	dojo.xhrGet({
+        url: "/pde/site" + dojo.doc.location.hash.substring(1), 
+        handleAs: "json-comment-filtered",
+        timeout: 5000,
+        load: function(jsonData, ioArgs) {
+          createTree(jsonData);
+          return jsonData;
+        },
+        error: function(response, ioArgs) {
+		  if (ioArgs.xhr && (ioArgs.xhr.status == 403)) {
+		    dojo.doc.location.href="/pde/login?nextURL=" + encodeURIComponent(dojo.doc.location.pathname) + encodeURIComponent(dojo.doc.location.search) + encodeURIComponent(dojo.doc.location.hash);
+		  }
+		  console.error("HTTP status code: ", ioArgs.xhr.status);
+		  return response;
+        }
+    });
+});
+		
+function createTree(jsonData){
+	for (var c in jsonData.categoryDef) {
+	  var category = jsonData.categoryDef[c];
+	  treeRoot.categories[category.name] = category;
+	  treeRoot.children.push(category);
+	}
+	for (var f in jsonData.feature) {
+	  var feature = jsonData.feature[f];
+	  if (feature["category"]) {
+	    var category = treeRoot.categories[feature["category"].name];
+	    if (category) {
+	      if (!category.children) {
+	        category.children = [];
+	      }
+	      category.children.push(feature);
+	    } else {
+	      treeRoot.children.push(feature);
+	    }
+	  } else {
+	    treeRoot.children.push(feature);
+	  }
+	}
+	var Model = function(root) { this.root=root; };
+	Model.prototype = modelPrototype;
+	var model = new Model(treeRoot);
+	var detailConnections = [];
+	function bind(connections, inputID, domAttribute, modelObject, modelAttribute) {
+		var inputElement = dojo.byId(inputID);
+		inputElement[domAttribute] = modelObject[modelAttribute];
+		connections.push(
+			dojo.connect(inputElement, "onchange", function() {
+				modelObject[modelAttribute] = inputElement[domAttribute];
+				model.onChange(modelObject);
+			})
+		);
+		connections.push(
+			dojo.connect(inputElement, "onkeypress", function() {
+				model.onChange(modelObject);
+			})
+		);
+	}
+	myTree = new dijit.Tree({
+		id: "myTree",
+		model: model,
+		showRoot: false,
+		getLabel: function(item) {
+		    if (item.id) {
+		      return item.id + (item.version?(" ("+item.version+")"):"");
+		    } else {
+		      return item.label;
+		    }
+		},
+		onClick: function(item,treeNode) {
+			if (item.id) {
+				dojo.byId("categoryProperties").style.display="none";
+				dojo.forEach(detailConnections, dojo.disconnect);
+				bind(detailConnections, "featureID", "value", item, "id");
+				bind(detailConnections, "featureVersion", "value", item, "version");
+				bind(detailConnections, "featureURL", "value", item, "url");
+				dojo.byId("featureProperties").style.display="block";
+			} else {
+				dojo.byId("featureProperties").style.display="none";
+				dojo.forEach(detailConnections, dojo.disconnect);
+				bind(detailConnections, "categoryID", "value", item, "name");
+				bind(detailConnections, "categoryName", "value", item, "label");
+				bind(detailConnections, "categoryDescription", "innerText", item, "description");
+				dojo.byId("categoryProperties").style.display="block";
+			}
+		},
+		getIconClass: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+			return item.id ? "featureItem" : "categoryItem";
+		}
+	});
+	myTree.startup();
+	dojo.byId("tree").appendChild(myTree.domNode);
+    dojo.connect(dojo.byId('newCategory'), 'onclick', function() {
+    	var newCategory = {
+         "description":"",
+         "label":"New Category",
+         "name":"newCategory"
+      	};
+    	treeRoot.children.push(newCategory);
+    	model.onChildrenChange(treeRoot, treeRoot.children);
+    	var node = myTree._itemNodeMap["newCategory"];
+    	myTree.focusNode(node);
+    	myTree.onClick(newCategory, node);
+    });
+    dojo.connect(dojo.byId('addFeature'), 'onclick', function() {
+	    var featureStore = new dojo.data.ItemFileReadStore({
+	            url: "/pde/features/"
+	    });
+	    var featureSelectWidget = dijit.byId("featureSelect");
+	    if (featureSelectWidget) {
+	    	// since "featureSelectWidget.reset();" doesn't work:
+	    	featureSelectWidget._hasBeenBlurred = false;
+	    	featureSelectWidget.setDisplayedValue("");
+	    } else {
+		    featureSelectWidget = new dijit.form.FilteringSelect({
+		        id: "featureSelect",
+		        name: "id",
+		        store: featureStore,
+		        searchAttr: "id"
+		    }, "featureSelect");
+		}
+		var dialog = dijit.byId('featureDialog');
+		dojo.connect(dialog, "onExecute", function() {
+	    	var newFeature = {
+	         "category":null,
+	         "url":""
+			};
+			var id = dijit.byId("featureSelect").getValue();
+			var newFeature = featureSelectWidget.store._getItemByIdentity(id);
+	    	treeRoot.children.push(newFeature);
+    		model.onChildrenChange(treeRoot, treeRoot.children);
+	    	var node = myTree._itemNodeMap[newFeature.id];
+	    	myTree.focusNode(node);
+	    	myTree.onClick(newFeature, node);
+		});
+    	dialog.show();
+    });
+    dojo.connect(dojo.byId('synchronize'), 'onclick', function() {
+    	alert("Sorry - 'Synchronize' is not yet implemented.");
+    });
+    dojo.connect(dojo.byId('build'), 'onclick', function() {
+    	alert("Sorry - 'Build' is not yet implemented.");
+    });
+    dojo.connect(dojo.byId('buildAll'), 'onclick', function() {
+    	alert("Sorry - 'BuildAll' is not yet implemented.");
+    });
+    window.e4.saveable.doSave("doSave();");
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/.classpath b/bundles/org.eclipse.e4.ui.css.jface/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.css.jface/.project b/bundles/org.eclipse.e4.ui.css.jface/.project
new file mode 100644
index 0000000..a6aab21
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.css.jface</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.css.jface/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.css.jface/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..28f50da
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Tue Nov 18 20:31:15 EST 2008
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/bundles/org.eclipse.e4.ui.css.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.css.jface/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9a3188f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.e4.ui.css.jface
+Bundle-Version: 0.9.0.qualifier
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-Activator: org.eclipse.e4.ui.css.jface.Activator
+Require-Bundle: org.eclipse.ui;bundle-version="3.4.1",
+ org.eclipse.core.runtime;bundle-version="3.4.0",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.e4.ui.css.jface;x-internal:=true,
+ org.eclipse.e4.ui.css.jface.viewers;x-internal:=true
diff --git a/bundles/org.eclipse.e4.ui.css.jface/about.html b/bundles/org.eclipse.e4.ui.css.jface/about.html
new file mode 100644
index 0000000..3ce4e7e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>November 20, 2008</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.css.jface/build.properties b/bundles/org.eclipse.e4.ui.css.jface/build.properties
new file mode 100644
index 0000000..9d06aea
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2010 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               about.html,\
+               plugin.properties
diff --git a/bundles/org.eclipse.e4.ui.css.jface/plugin.properties b/bundles/org.eclipse.e4.ui.css.jface/plugin.properties
new file mode 100644
index 0000000..cdff0c5
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2010 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+pluginName = Eclipse CSS JFace Support
+providerName = Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/Activator.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/Activator.java
new file mode 100644
index 0000000..faa99f0
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.jface;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.e4.ui.css.jface";
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSBaseLabelProvider.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSBaseLabelProvider.java
new file mode 100644
index 0000000..d0d5310
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSBaseLabelProvider.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.jface.viewers;
+
+import org.eclipse.e4.ui.css.core.css2.CSS2FontPropertiesHelpers;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.CSS2FontProperties;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.css.CSSValue;
+
+public class CSSBaseLabelProvider extends LabelProvider {
+
+	protected CSSEngine engine;
+	protected StructuredViewer viewer;
+
+	public CSSBaseLabelProvider(CSSEngine engine, StructuredViewer viewer) {
+		this.engine = engine;
+		this.viewer = viewer;
+	}
+
+	protected Font getFont(Object element, String propertyName, int columnIndex) {
+		Widget widget = getWidget(element, columnIndex);
+		return getFont(widget, propertyName);
+	}
+
+	protected Font getFont(Object element, String propertyName) {
+		Widget widget = getWidget(element);
+		return getFont(widget, propertyName);
+	}
+
+	protected Font getFont(Widget widget, String propertyName) {
+		CSSValue value = getCSSValue(widget, propertyName);
+		if (value == null)
+			return null;
+		CSS2FontProperties fontProperties = CSS2FontPropertiesHelpers
+				.createCSS2FontProperties(value, propertyName);
+		try {
+			return (Font) engine.convert(fontProperties, Font.class, widget
+					.getDisplay());
+		} catch (Exception e) {
+			engine.handleExceptions(e);
+		}
+		return null;
+	}
+
+	protected Image getImage(Object element, String propertyName,
+			int columnIndex) {
+		Widget widget = getWidget(element, columnIndex);
+		return getImage(widget, propertyName);
+	}
+
+	protected Image getImage(Object element, String propertyName) {
+		Widget widget = getWidget(element);
+		return getImage(widget, propertyName);
+	}
+
+	protected Image getImage(Widget widget, String propertyName) {
+		return (Image) getResource(widget, propertyName, Image.class);
+	}
+
+	protected Color getColor(Object element, String propertyName,
+			int columnIndex) {
+		Widget widget = getWidget(element, columnIndex);
+		return getColor(widget, propertyName);
+	}
+
+	protected Color getColor(Object element, String propertyName) {
+		Widget widget = getWidget(element);
+		return getColor(widget, propertyName);
+	}
+
+	protected Color getColor(Widget widget, String propertyName) {
+		return (Color) getResource(widget, propertyName, Color.class);
+	}
+
+	protected Object getResource(Widget widget, String propertyName,
+			Object toType) {
+		CSSValue value = getCSSValue(widget, propertyName);
+		if (value != null) {
+			try {
+				return engine.convert(value, toType, widget.getDisplay());
+			} catch (Exception e) {
+				engine.handleExceptions(e);
+			}
+		}
+		return null;
+	}
+
+	protected CSSValue getCSSValue(Widget widget, String propertyName) {
+		if (widget == null)
+			return null;
+		Element elt = engine.getElement(widget);
+		if (elt == null)
+			return null;
+		CSSStyleDeclaration styleDeclaration = engine.getViewCSS()
+				.getComputedStyle(elt, null);
+		if (styleDeclaration == null)
+			return null;
+
+		return styleDeclaration.getPropertyCSSValue(propertyName);
+	}
+
+	protected Widget getWidget(Object element) {
+		return viewer.testFindItem(element);
+	}
+
+	protected Widget getWidget(Object element, int columnIndex) {
+//		Widget[] widgets = viewer.testFindItems(element);
+//		if (widgets.length > columnIndex)
+//			return widgets[columnIndex];
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSLabelProvider.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSLabelProvider.java
new file mode 100644
index 0000000..e5d3c25
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSLabelProvider.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.jface.viewers;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.IFontProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class CSSLabelProvider extends CSSBaseLabelProvider implements
+		ILabelProvider, IColorProvider, IFontProvider {
+
+	public CSSLabelProvider(CSSEngine engine, TableViewer tableViewer) {
+		super(engine, tableViewer);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+	 */
+	public Image getImage(Object element) {
+		return getImage(element, "background-image");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
+	 */
+	public Color getBackground(Object element) {
+		return getColor(element, "background-color");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
+	 */
+	public Color getForeground(Object element) {
+		return getColor(element, "color");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object)
+	 */
+	public Font getFont(Object element) {
+		return getFont(element, "font");
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSTableLabelProvider.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSTableLabelProvider.java
new file mode 100644
index 0000000..e8db8a9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSTableLabelProvider.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.jface.viewers;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.jface.viewers.ITableColorProvider;
+import org.eclipse.jface.viewers.ITableFontProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+public abstract class CSSTableLabelProvider extends CSSBaseLabelProvider
+		implements ITableLabelProvider, ITableColorProvider, ITableFontProvider {
+
+	public CSSTableLabelProvider(CSSEngine engine, TableViewer tableViewer) {
+		super(engine, tableViewer);
+	}
+
+	public Color getBackground(Object element, int columnIndex) {
+		return getColor(element, "background-color", columnIndex);
+	}
+
+	public Font getFont(Object element, int columnIndex) {
+		return getFont(element, "font", columnIndex);
+	}
+
+	public Color getForeground(Object element, int columnIndex) {
+		return getColor(element, "color", columnIndex);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/.classpath b/bundles/org.eclipse.e4.ui.css.legacy/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/.project b/bundles/org.eclipse.e4.ui.css.legacy/.project
new file mode 100644
index 0000000..785b4ad
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.css.legacy</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.css.legacy/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..6d16c74
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Feb 25 20:08:17 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.css.legacy/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0ca6d41
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Legacy CSS Presentation Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.css.legacy;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Require-Bundle: org.eclipse.ui;bundle-version="[3.6.0,3.100.0)",
+ org.eclipse.core.runtime,
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.ui.css.legacy.presentation
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/build.properties b/bundles/org.eclipse.e4.ui.css.legacy/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/plugin.xml b/bundles/org.eclipse.e4.ui.css.legacy/plugin.xml
new file mode 100644
index 0000000..aa3ac36
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.presentationFactories">
+      <factory
+            class="org.eclipse.e4.ui.css.legacy.presentation.CSSPresentationFactory"
+            id="org.eclipse.e4.ui.css.legacy.presentation.presentationFactory"
+            name="CSS Presentation">
+      </factory>
+   </extension>
+</plugin>
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/css/legacy/presentation/CSSPresentationFactory.java b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/css/legacy/presentation/CSSPresentationFactory.java
new file mode 100644
index 0000000..2084ca1
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/css/legacy/presentation/CSSPresentationFactory.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.legacy.presentation;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.internal.css.legacy.presentation.CSSTabFolder;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultMultiTabListener;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultSimpleTabListener;
+import org.eclipse.ui.internal.presentations.util.PresentablePartFolder;
+import org.eclipse.ui.internal.presentations.util.StandardEditorSystemMenu;
+import org.eclipse.ui.internal.presentations.util.StandardViewSystemMenu;
+import org.eclipse.ui.internal.presentations.util.TabbedStackPresentation;
+import org.eclipse.ui.presentations.IStackPresentationSite;
+import org.eclipse.ui.presentations.StackPresentation;
+import org.eclipse.ui.presentations.WorkbenchPresentationFactory;
+
+/**
+ * 
+ * @since 3.5
+ * 
+ */
+public class CSSPresentationFactory extends
+		WorkbenchPresentationFactory {
+
+	public static String ID = "org.eclipse.e4.ui.css.legacy.presentation.presentationFactory";
+	
+	// don't reset these dynamically, so just keep the information static.
+	// see bug:
+	// 75422 [Presentations] Switching presentation to R21 switches immediately,
+	// but only partially
+	private static int editorTabPosition = PlatformUI.getPreferenceStore()
+			.getInt(IWorkbenchPreferenceConstants.EDITOR_TAB_POSITION);
+	private static int viewTabPosition = PlatformUI.getPreferenceStore()
+			.getInt(IWorkbenchPreferenceConstants.VIEW_TAB_POSITION);
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.presentations.AbstractPresentationFactory#createEditorPresentation(org.eclipse.swt.widgets.Composite,
+	 *      org.eclipse.ui.presentations.IStackPresentationSite)
+	 */
+	public StackPresentation createEditorPresentation(Composite parent,
+			IStackPresentationSite site) {
+		CSSTabFolder folder = new CSSTabFolder(parent,
+				editorTabPosition | SWT.BORDER, site
+						.supportsState(IStackPresentationSite.STATE_MINIMIZED),
+				site.supportsState(IStackPresentationSite.STATE_MAXIMIZED));
+
+		/*
+		 * Set the minimum characters to display, if the preference is something
+		 * other than the default. This is mainly intended for RCP applications
+		 * or for expert users (i.e., via the plug-in customization file).
+		 * 
+		 * Bug 32789.
+		 */
+		final IPreferenceStore store = PlatformUI.getPreferenceStore();
+		if (store
+				.contains(IWorkbenchPreferenceConstants.EDITOR_MINIMUM_CHARACTERS)) {
+			final int minimumCharacters = store
+					.getInt(IWorkbenchPreferenceConstants.EDITOR_MINIMUM_CHARACTERS);
+			if (minimumCharacters >= 0) {
+				folder.setMinimumCharacters(minimumCharacters);
+			}
+		}
+
+		PresentablePartFolder partFolder = new PresentablePartFolder(folder);
+
+		TabbedStackPresentation result = new TabbedStackPresentation(site,
+				partFolder, new StandardEditorSystemMenu(site));
+
+		new DefaultMultiTabListener(result.getApiPreferences(),
+				IWorkbenchPreferenceConstants.SHOW_MULTIPLE_EDITOR_TABS, folder);
+
+		new DefaultSimpleTabListener(result.getApiPreferences(),
+				IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS,
+				folder);
+
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.presentations.AbstractPresentationFactory#createViewPresentation(org.eclipse.swt.widgets.Composite,
+	 *      org.eclipse.ui.presentations.IStackPresentationSite)
+	 */
+	public StackPresentation createViewPresentation(Composite parent,
+			IStackPresentationSite site) {
+
+		CSSTabFolder folder = new CSSTabFolder(parent, viewTabPosition
+				| SWT.BORDER, site
+				.supportsState(IStackPresentationSite.STATE_MINIMIZED), site
+				.supportsState(IStackPresentationSite.STATE_MAXIMIZED));
+
+		final IPreferenceStore store = PlatformUI.getPreferenceStore();
+		final int minimumCharacters = store
+				.getInt(IWorkbenchPreferenceConstants.VIEW_MINIMUM_CHARACTERS);
+		if (minimumCharacters >= 0) {
+			folder.setMinimumCharacters(minimumCharacters);
+		}
+
+		PresentablePartFolder partFolder = new PresentablePartFolder(folder);
+
+		folder.setUnselectedCloseVisible(false);
+		folder.setUnselectedImageVisible(true);
+
+		TabbedStackPresentation result = new TabbedStackPresentation(site,
+				partFolder, new StandardViewSystemMenu(site));
+
+		new DefaultSimpleTabListener(result.getApiPreferences(),
+				IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS,
+				folder);
+
+		return result;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/internal/css/legacy/presentation/CSSTabFolder.java b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/internal/css/legacy/presentation/CSSTabFolder.java
new file mode 100644
index 0000000..b6155f8
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/internal/css/legacy/presentation/CSSTabFolder.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.css.legacy.presentation;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabItem;
+import org.eclipse.ui.internal.presentations.util.AbstractTabItem;
+
+/**
+ * @since 3.5
+ */
+public class CSSTabFolder extends DefaultTabFolder {
+
+	public CSSTabFolder(Composite parent, int flags, boolean allowMin,
+			boolean allowMax) {
+		super(parent, flags, allowMin, allowMax);
+		// TODO Auto-generated constructor stub
+	}
+    public void updateColors() {
+    	//do nothing, CSS will handle
+    }
+    
+    public AbstractTabItem add(int index, int flags) {
+    	DefaultTabItem result = (DefaultTabItem) super.add(index, flags);  
+    	Widget widget = result.getWidget();
+
+    	CSSEngine engine = getEngine(widget.getDisplay());
+    	if(engine != null) {
+    		engine.applyStyles(widget, true);
+    	}
+    	
+        return result;
+    }
+    
+	private CSSEngine getEngine(Display display) {
+		//TODO post 0.9 this can be retrieved via API on SWTElement
+		return (CSSEngine) display.getData("org.eclipse.e4.ui.css.core.engine");
+	}
+
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/.classpath b/bundles/org.eclipse.e4.ui.css.nebula/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/.project b/bundles/org.eclipse.e4.ui.css.nebula/.project
new file mode 100644
index 0000000..ef335c8
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.css.nebula</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.css.nebula/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9b6c36f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Jan 28 17:50:20 EST 2009
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.css.nebula/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e739188
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: CSS Nebula Support Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.css.nebula
+Bundle-Version: 0.9.0.qualifier
+Require-Bundle: org.eclipse.swt;bundle-version="3.4.1",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0",
+ org.eclipse.e4.ui.css.swt;bundle-version="0.9.0",
+ org.eclipse.nebula.widgets.gallery;bundle-version="1.0.0",
+ org.w3c.css.sac;bundle-version="1.3.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.e4.ui.css.nebula.dom,
+ org.eclipse.e4.ui.css.nebula.engine,
+ org.eclipse.e4.ui.css.nebula.gallery,
+ org.eclipse.e4.ui.css.nebula.helpers,
+ org.eclipse.e4.ui.css.nebula.properties.css2
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/build.properties b/bundles/org.eclipse.e4.ui.css.nebula/build.properties
new file mode 100644
index 0000000..dd019cd
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/build.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2010 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElement.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElement.java
new file mode 100644
index 0000000..c8451be
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElement.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.dom;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.swt.dom.WidgetElement;
+import org.eclipse.nebula.widgets.gallery.Gallery;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class NebulaElement extends WidgetElement {
+
+	public NebulaElement(Widget widget, CSSEngine engine) {
+		super(widget, engine);
+	}
+
+	public NodeList getChildNodes() {
+		return super.getChildNodes();
+	}
+
+	protected void computeStaticPseudoInstances() {
+		Widget widget = getWidget();
+		if (widget instanceof GalleryItem) {
+			// it's GalleryItem. Set selected as static pseudo instance.
+			// because this widget define methods
+			// GalleryItem#setSelectionBackground (Color color)
+			// which set background Color when a CTabItem is selected.
+			super.addStaticPseudoInstance("selected");
+		}
+		super.computeStaticPseudoInstances();
+	}
+
+	public Node getParentNode() {
+		Widget widget = getWidget();
+		if (widget instanceof GalleryItem) {
+			GalleryItem galleryItem = (GalleryItem) widget;
+			Widget parent = galleryItem.getParentItem();
+			if (parent == null)
+				parent = galleryItem.getParent();
+			if (parent != null) {
+				Element element = getElement(parent);
+				return element;
+			}
+		}
+		return super.getParentNode();
+	}
+
+	public int getLength() {
+		Widget widget = getWidget();
+		if (widget instanceof Gallery) {
+			Gallery gallery = (Gallery) widget;
+			return gallery.getItemCount();
+		}
+		if (widget instanceof GalleryItem) {
+			GalleryItem galleryItem = (GalleryItem) widget;
+			return galleryItem.getItemCount();
+		}
+		return super.getLength();
+	}
+
+	public Node item(int index) {
+		Widget widget = getWidget();
+		if (widget instanceof Gallery) {
+			Gallery gallery = (Gallery) widget;
+			GalleryItem galleryItem = gallery.getItem(index);
+			return getElement(galleryItem);
+		}
+		if (widget instanceof GalleryItem) {
+			GalleryItem galleryItem = (GalleryItem) widget;
+			GalleryItem galleryItemChild = galleryItem.getItem(index);
+			return getElement(galleryItemChild);
+		}
+		return super.item(index);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElementProvider.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElementProvider.java
new file mode 100644
index 0000000..cdef92e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElementProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.dom;
+
+import org.eclipse.e4.ui.css.core.dom.IElementProvider;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.helpers.NebulaElementHelpers;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+
+/**
+ * {@link IElementProvider} SWT and Nebula widget implementation to retrieve w3c
+ * Element {@link SWTElement} linked to SWT widget.
+ * 
+ * @version 1.0.0
+ * @author <a href="mailto:angelo.zerr@gmail.com">Angelo ZERR</a>
+ * 
+ */
+public class NebulaElementProvider implements IElementProvider {
+
+	public static final IElementProvider INSTANCE = new NebulaElementProvider();
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.e4.ui.css.swt.dom.SWTElementProvider#getElement(java.lang.Object,
+	 *      org.eclipse.e4.ui.css.core.engine.CSSEngine)
+	 */
+	public Element getElement(Object element, CSSEngine engine) {
+		if (element instanceof Widget) {
+			// element is SWT Widget
+			Widget widget = (Widget) element;
+			// Return the w3c Element linked to the SWT widget.
+			return NebulaElementHelpers.getElement(widget, engine);
+		}
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/engine/CSSNebulaEngineImpl.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/engine/CSSNebulaEngineImpl.java
new file mode 100644
index 0000000..9419348
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/engine/CSSNebulaEngineImpl.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *     IBM Corporation - ongoing development
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.engine;
+
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyBackgroundHandler;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyTextHandler;
+import org.eclipse.e4.ui.css.nebula.dom.NebulaElementProvider;
+import org.eclipse.e4.ui.css.nebula.properties.css2.CSSPropertyBackgroundNebulaHandler;
+import org.eclipse.e4.ui.css.nebula.properties.css2.CSSPropertyTextNebulaHandler;
+import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl;
+import org.eclipse.swt.widgets.Display;
+
+public class CSSNebulaEngineImpl extends CSSSWTEngineImpl {
+
+	public CSSNebulaEngineImpl(Display display) {
+		super(display);
+		this.initializeNebulaConfig();
+	}
+
+	public CSSNebulaEngineImpl(Display display, boolean lazyApplyingStyles) {
+		super(display, lazyApplyingStyles);
+		this.initializeNebulaConfig();
+	}
+
+	protected void initializeNebulaConfig() {
+		// Register Nebula Element Provider to retrieve
+		// w3c Element NebulaElement which wrap SWT/Nebula widget.
+		super.setElementProvider(NebulaElementProvider.INSTANCE);
+	}
+
+	protected void initializeCSSPropertyHandlers() {
+		// Register Nebula CSS Property Background Handler
+		super.registerCSSPropertyHandler(ICSSPropertyBackgroundHandler.class,
+				CSSPropertyBackgroundNebulaHandler.INSTANCE);
+		// Register Nebula CSS Property Text Handler
+		super.registerCSSPropertyHandler(ICSSPropertyTextHandler.class,
+				CSSPropertyTextNebulaHandler.INSTANCE);
+		super.initializeCSSPropertyHandlers();		
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/DefaultGalleryItemRendererDelegate.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/DefaultGalleryItemRendererDelegate.java
new file mode 100644
index 0000000..32ff93b
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/DefaultGalleryItemRendererDelegate.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.gallery;
+
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer;
+import org.eclipse.swt.graphics.Color;
+
+public class DefaultGalleryItemRendererDelegate implements IGalleryItemRenderer {
+
+	private DefaultGalleryItemRenderer itemRenderer;
+
+	public DefaultGalleryItemRendererDelegate(
+			DefaultGalleryItemRenderer itemRenderer) {
+		this.itemRenderer = itemRenderer;
+	}
+
+	public Color getBackgroundColor() {
+		return itemRenderer.getBackgroundColor();
+	}
+
+	public Color getForegroundColor() {
+		return itemRenderer.getForegroundColor();
+	}
+
+	public Color getSelectionBackgroundColor() {
+		return itemRenderer.getSelectionBackgroundColor();
+	}
+
+	public Color getSelectionForegroundColor() {
+		return itemRenderer.getSelectionForegroundColor();
+	}
+
+	public void setBackgroundColor(Color backgroundColor) {
+		itemRenderer.setBackgroundColor(backgroundColor);
+	}
+
+	public void setForegroundColor(Color foregroundColor) {
+		itemRenderer.setForegroundColor(foregroundColor);
+	}
+
+	public void setSelectionBackgroundColor(Color selectionBackgroundColor) {
+		itemRenderer.setSelectionBackgroundColor(selectionBackgroundColor);
+	}
+
+	public void setSelectionForegroundColor(Color selectionForegroundColor) {
+		itemRenderer.setSelectionForegroundColor(selectionForegroundColor);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/IGalleryItemRenderer.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/IGalleryItemRenderer.java
new file mode 100644
index 0000000..9e5e93f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/IGalleryItemRenderer.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.gallery;
+
+import org.eclipse.swt.graphics.Color;
+
+public interface IGalleryItemRenderer {
+
+	public Color getForegroundColor();
+
+	public void setForegroundColor(Color foregroundColor);
+
+	public Color getSelectionForegroundColor();
+
+	public void setSelectionForegroundColor(Color selectionForegroundColor);
+
+	public Color getSelectionBackgroundColor();
+
+	public void setSelectionBackgroundColor(Color selectionBackgroundColor);
+
+	public Color getBackgroundColor();
+
+	public void setBackgroundColor(Color backgroundColor);
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/ListItemRendererDelegate.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/ListItemRendererDelegate.java
new file mode 100644
index 0000000..cbbdd3b
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/ListItemRendererDelegate.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.gallery;
+
+import org.eclipse.nebula.widgets.gallery.ListItemRenderer;
+import org.eclipse.swt.graphics.Color;
+
+public class ListItemRendererDelegate implements IGalleryItemRenderer {
+
+	private ListItemRenderer itemRenderer;
+
+	public ListItemRendererDelegate(
+			ListItemRenderer itemRenderer) {
+		this.itemRenderer = itemRenderer;
+	}
+
+	public Color getBackgroundColor() {
+		return itemRenderer.getBackgroundColor();
+	}
+
+	public Color getForegroundColor() {
+		return itemRenderer.getForegroundColor();
+	}
+
+	public Color getSelectionBackgroundColor() {
+		return itemRenderer.getSelectionBackgroundColor();
+	}
+
+	public Color getSelectionForegroundColor() {
+		return itemRenderer.getSelectionForegroundColor();
+	}
+
+	public void setBackgroundColor(Color backgroundColor) {
+		itemRenderer.setBackgroundColor(backgroundColor);
+	}
+
+	public void setForegroundColor(Color foregroundColor) {
+		itemRenderer.setForegroundColor(foregroundColor);
+	}
+
+	public void setSelectionBackgroundColor(Color selectionBackgroundColor) {
+		itemRenderer.setSelectionBackgroundColor(selectionBackgroundColor);
+	}
+
+	public void setSelectionForegroundColor(Color selectionForegroundColor) {
+		itemRenderer.setSelectionForegroundColor(selectionForegroundColor);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/GalleryHelpers.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/GalleryHelpers.java
new file mode 100644
index 0000000..96a4ae0
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/GalleryHelpers.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.helpers;
+
+import org.eclipse.e4.ui.css.nebula.gallery.DefaultGalleryItemRendererDelegate;
+import org.eclipse.e4.ui.css.nebula.gallery.IGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.Gallery;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.graphics.Color;
+
+public class GalleryHelpers {
+
+	private static final String ITEM_RENDERER_KEY = "org.eclipse.e4.ui.css.nebula.helpers.ITEM_RENDERER_KEY";
+
+	public static AbstractGalleryItemRenderer getItemRenderer(
+			GalleryItem galleryItem) {
+		return getItemRenderer(galleryItem.getParent());
+	}
+
+	public static AbstractGalleryItemRenderer getItemRenderer(Gallery gallery) {
+
+		return gallery.getItemRenderer();
+	}
+
+	public static Color getSelectionBackgroundColor(Gallery gallery) {
+		IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+		if (itemRenderer != null) {
+			return itemRenderer.getSelectionBackgroundColor();
+		}
+		return null;
+	}
+
+	public static void setSelectionBackgroundColor(Gallery gallery, Color color) {
+		IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+		if (itemRenderer != null) {
+			itemRenderer.setSelectionBackgroundColor(color);
+		}
+	}
+
+	public static Color getSelectionForegroundColor(Gallery gallery) {
+		IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+		if (itemRenderer != null) {
+			return itemRenderer.getSelectionForegroundColor();
+		}
+		return null;
+	}
+
+	public static void setSelectionForegroundColor(Gallery gallery, Color color) {
+		IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+		if (itemRenderer != null) {
+			itemRenderer.setSelectionForegroundColor(color);
+		}
+	}
+
+	public static IGalleryItemRenderer getGalleryItemRenderer(Gallery gallery) {
+		AbstractGalleryItemRenderer itemRenderer = gallery.getItemRenderer();
+		if (itemRenderer instanceof IGalleryItemRenderer)
+			return (IGalleryItemRenderer) itemRenderer;
+		IGalleryItemRenderer galleryItemRenderer = (IGalleryItemRenderer) gallery
+				.getData(ITEM_RENDERER_KEY);
+		if (galleryItemRenderer != null)
+			return galleryItemRenderer;
+		// DefaultGalleryItemRenderer
+		if (itemRenderer instanceof DefaultGalleryItemRenderer) {
+			galleryItemRenderer = new DefaultGalleryItemRendererDelegate(
+					(DefaultGalleryItemRenderer) itemRenderer);			
+		}
+		// DefaultGalleryItemRenderer
+		if (itemRenderer instanceof DefaultGalleryItemRenderer) {
+			galleryItemRenderer = new DefaultGalleryItemRendererDelegate(
+					(DefaultGalleryItemRenderer) itemRenderer);			
+		}
+		if (galleryItemRenderer != null)
+			gallery.setData(ITEM_RENDERER_KEY, galleryItemRenderer);
+		return galleryItemRenderer;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/NebulaElementHelpers.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/NebulaElementHelpers.java
new file mode 100644
index 0000000..303c03f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/NebulaElementHelpers.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.helpers;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.dom.NebulaElement;
+import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+
+public class NebulaElementHelpers extends SWTElementHelpers {
+
+	/**
+	 * Return the w3c Element linked to the SWT widget.
+	 * 
+	 * @param widget
+	 * @return
+	 */
+	public static Element getElement(Widget widget, CSSEngine engine) {
+		try {
+			return getElement(widget, engine, NebulaElement.class);
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	public static boolean isNebulaWidget(Object element) {
+		Widget widget = getWidget(element);
+		if (widget instanceof GalleryItem)
+			return true;
+		return false;
+
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyBackgroundNebulaHandler.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyBackgroundNebulaHandler.java
new file mode 100644
index 0000000..f07cd80
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyBackgroundNebulaHandler.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.properties.css2;
+
+import org.eclipse.e4.ui.css.core.dom.properties.css2.AbstractCSSPropertyBackgroundHandler;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyBackgroundHandler;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.helpers.GalleryHelpers;
+import org.eclipse.e4.ui.css.nebula.helpers.NebulaElementHelpers;
+import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.css.CSSValue;
+
+public class CSSPropertyBackgroundNebulaHandler extends
+		AbstractCSSPropertyBackgroundHandler {
+
+	public final static ICSSPropertyBackgroundHandler INSTANCE = new CSSPropertyBackgroundNebulaHandler();
+
+	public boolean applyCSSProperty(Object element, String property,
+			CSSValue value, String pseudo, CSSEngine engine) throws Exception {
+		if (!NebulaElementHelpers.isNebulaWidget(element))
+			return false;
+		Widget widget = SWTElementHelpers.getWidget(element);
+		if (widget != null) {
+			super.applyCSSProperty(widget, property, value, pseudo, engine);
+			return true;
+		}
+		return false;
+	}
+
+	public String retrieveCSSProperty(Object element, String property,
+			String pseudo, CSSEngine engine) throws Exception {
+		if (!NebulaElementHelpers.isNebulaWidget(element))
+			return null;
+		Widget widget = SWTElementHelpers.getWidget(element);
+		if (widget != null) {
+			return super.retrieveCSSProperty(widget, property, pseudo, engine);
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.e4.ui.core.css.dom.properties.css2.AbstractCSSPropertyBackgroundHandler#applyCSSPropertyBackgroundColor(java.lang.Object,
+	 *      org.w3c.dom.css.CSSValue, java.lang.String,
+	 *      org.eclipse.e4.ui.core.css.engine.CSSEngine)
+	 */
+	public void applyCSSPropertyBackgroundColor(Object element, CSSValue value,
+			String pseudo, CSSEngine engine) throws Exception {
+		Widget widget = (Widget) element;
+		if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+			Color newColor = (Color) engine.convert(value, Color.class, widget
+					.getDisplay());
+			if (widget instanceof GalleryItem) {
+				GalleryItem galleryItem = (GalleryItem) widget;
+				if ("selected".equals(pseudo)) {
+					GalleryHelpers.setSelectionBackgroundColor(galleryItem
+							.getParent(), newColor);
+				} else
+					galleryItem.setBackground(newColor);
+
+			} else {
+				if (widget instanceof Control)
+					((Control) widget).setBackground(newColor);
+			}
+		}
+	}
+
+	public String retrieveCSSPropertyBackgroundAttachment(Object element,
+			String pseudo, CSSEngine engine) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String retrieveCSSPropertyBackgroundColor(Object element,
+			String pseudo, CSSEngine engine) throws Exception {
+		Widget widget = (Widget) element;
+		Color color = null;
+		if (widget instanceof GalleryItem) {
+			GalleryItem galleryItem = (GalleryItem) widget;
+			if ("selected".equals(pseudo)) {
+				color = GalleryHelpers.getSelectionBackgroundColor(galleryItem
+						.getParent());
+			} else {
+				color = galleryItem.getBackground();
+			}
+		}
+		if (color != null) {
+			return engine.convert(color, Color.class, null);
+		}
+		return null;
+	}
+
+	public String retrieveCSSPropertyBackgroundImage(Object element,
+			String pseudo, CSSEngine engine) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String retrieveCSSPropertyBackgroundPosition(Object element,
+			String pseudo, CSSEngine engine) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public String retrieveCSSPropertyBackgroundRepeat(Object element,
+			String pseudo, CSSEngine engine) throws Exception {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyTextNebulaHandler.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyTextNebulaHandler.java
new file mode 100644
index 0000000..3e6f896
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyTextNebulaHandler.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.properties.css2;
+
+import org.eclipse.e4.ui.css.core.dom.properties.css2.AbstractCSSPropertyTextHandler;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyTextHandler;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.helpers.GalleryHelpers;
+import org.eclipse.e4.ui.css.nebula.helpers.NebulaElementHelpers;
+import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.css.CSSValue;
+
+public class CSSPropertyTextNebulaHandler extends
+		AbstractCSSPropertyTextHandler {
+
+	public final static ICSSPropertyTextHandler INSTANCE = new CSSPropertyTextNebulaHandler();
+
+	public boolean applyCSSProperty(Object element, String property,
+			CSSValue value, String pseudo, CSSEngine engine) throws Exception {
+		if (!NebulaElementHelpers.isNebulaWidget(element))
+			return false;
+		Widget widget = SWTElementHelpers.getWidget(element);
+		if (widget != null) {
+			super.applyCSSProperty(widget, property, value, pseudo, engine);
+			return true;
+		}
+		return false;
+
+	}
+
+	public String retrieveCSSProperty(Object element, String property,
+			String pseudo, CSSEngine engine) throws Exception {
+		if (!NebulaElementHelpers.isNebulaWidget(element))
+			return null;
+		Widget widget = SWTElementHelpers.getWidget(element);
+		if (widget != null) {
+			return super.retrieveCSSProperty(widget, property, pseudo, engine);
+		}
+		return null;
+	}
+
+	public void applyCSSPropertyColor(Object element, CSSValue value,
+			String pseudo, CSSEngine engine) throws Exception {
+		Widget widget = (Widget) element;
+		if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+			Color newColor = (Color) engine.convert(value, Color.class, widget
+					.getDisplay());
+			if (widget instanceof GalleryItem) {
+				GalleryItem galleryItem = (GalleryItem) widget;
+				if ("selected".equals(pseudo)) {
+					GalleryHelpers.setSelectionForegroundColor(galleryItem
+							.getParent(), newColor);
+				} else
+					galleryItem.setForeground(newColor);
+
+			} else {
+				if (widget instanceof Control)
+					((Control) widget).setForeground(newColor);
+			}
+		}
+	}
+
+	public String retrieveCSSPropertyColor(Object element, String pseudo,
+			CSSEngine engine) throws Exception {
+		Widget widget = (Widget) element;
+		Color color = null;
+		if (widget instanceof GalleryItem) {
+			GalleryItem galleryItem = (GalleryItem) widget;
+			if ("selected".equals(pseudo)) {
+				color = GalleryHelpers.getSelectionForegroundColor(galleryItem
+						.getParent());
+			} else {
+				color = galleryItem.getForeground();
+			}
+		}
+		if (color != null) {
+			return engine.convert(color, Color.class, null);
+		}
+		return null;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.classpath b/bundles/org.eclipse.e4.ui.gadgets/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.project b/bundles/org.eclipse.e4.ui.gadgets/.project
new file mode 100644
index 0000000..3a5d0f9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.gadgets</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..43fb5cd
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri Oct 09 16:11:38 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..69bb514
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,55 @@
+#Sat Oct 24 21:58:57 CEST 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.gadgets/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.gadgets/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2b15ea3
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Opensocial-demo
+Bundle-SymbolicName: org.eclipse.e4.ui.gadgets;singleton:=true
+Bundle-Version: 0.9.2.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.equinox.registry;bundle-version="3.4.0",
+ org.eclipse.core.jobs;bundle-version="3.4.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ javax.servlet;bundle-version="2.5.0",
+ org.eclipse.ui.views;bundle-version="3.5.0",
+ org.eclipse.e4.ui.web;bundle-version="0.9.0"
+Import-Package: org.apache.commons.httpclient;version="3.0.0",
+ org.apache.commons.httpclient.methods;version="3.0.0",
+ org.osgi.framework;version="1.5.0"
+Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.eclipse.e4.ui.gadgets/build.properties b/bundles/org.eclipse.e4.ui.gadgets/build.properties
new file mode 100644
index 0000000..8274abe
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               js/,\
+               icons/
diff --git a/bundles/org.eclipse.e4.ui.gadgets/icons/full/dlcl16/refresh.gif b/bundles/org.eclipse.e4.ui.gadgets/icons/full/dlcl16/refresh.gif
new file mode 100644
index 0000000..6eafa48
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/icons/full/dlcl16/refresh.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.ui.gadgets/icons/full/elcl16/refresh.gif b/bundles/org.eclipse.e4.ui.gadgets/icons/full/elcl16/refresh.gif
new file mode 100644
index 0000000..e383147
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/icons/full/elcl16/refresh.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/io.js b/bundles/org.eclipse.e4.ui.gadgets/js/io.js
new file mode 100644
index 0000000..2cf910c
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/io.js
@@ -0,0 +1,47 @@
+var gadgets = gadgets || {};
+
+gadgets.io = function() {
+	return {
+		makeRequest : function(url, callback, params) {
+			try {
+				// Retrieve parameters to forward them to the java part
+				var method = params[gadgets.io.RequestParameters.METHOD];
+				var contentType = params[gadgets.io.RequestParameters.CONTENT_TYPE];
+				
+				// All headers will be converted in a single String. The format will be :
+				// headerName#headerValue>header2Name#header2Value
+				var headers = params[gadgets.io.RequestParameters.HEADERS];
+				var headersStr = "" ;
+				if (headers != null) {
+					headersStr = "Authorization#" + headers["Authorization"];
+					headersStr += "\n" + "ContentType#" + headers["ContentType"];
+				}
+
+				var postData = params[gadgets.io.RequestParameters.POST_DATA];
+
+				e4_makeXmlHttpRequest(url, callback.toString(), method,
+						contentType, headersStr, postData);
+			} catch (err) {
+				// FIXME: this should not happen, but for some reason
+				// e4_makeXmlHttpRequest is not declared at the very beginning
+				// of the execution...
+			}
+
+		}
+	}
+}();
+
+gadgets.io.RequestParameters = gadgets.util.makeEnum( [ "METHOD",
+		"CONTENT_TYPE", "POST_DATA", "HEADERS", "AUTHORIZATION", "NUM_ENTRIES",
+		"GET_SUMMARIES", "REFRESH_INTERVAL", "OAUTH_SERVICE_NAME",
+		"OAUTH_USE_TOKEN", "OAUTH_TOKEN_NAME", "OAUTH_REQUEST_TOKEN",
+		"OAUTH_REQUEST_TOKEN_SECRET" ]);
+
+gadgets.io.MethodType = gadgets.util.makeEnum( [ "GET", "POST", "PUT",
+		"DELETE", "HEAD" ]);
+
+gadgets.io.ContentType = gadgets.util
+		.makeEnum( [ "TEXT", "DOM", "JSON", "FEED" ]);
+
+gadgets.io.AuthorizationType = gadgets.util.makeEnum( [ "NONE", "SIGNED",
+		"OAUTH" ]);
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/misc.js b/bundles/org.eclipse.e4.ui.gadgets/js/misc.js
new file mode 100644
index 0000000..773add4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/misc.js
@@ -0,0 +1,29 @@
+function _IG_LoadLibraryDeferred(url, callback) {
+  var scriptElement = document.createElement("script");
+  scriptElement.src=url;
+  document.getElementsByTagName("head")[0].appendChild(scriptElement);
+  setTimeout(function(){eval(callback)}, 1000);
+}
+function _gel(id) {
+  if(document.all) {
+    return document.all[id];
+  } else {
+    return document.getElementById(id);
+  }
+}
+function _IG_AddDOMEventHandler(domObject,event,callback){
+  if (domObject.addEventListener){
+    domObject.addEventListener(event, callback, true);}
+  else{
+    domObject.attachEvent('on'+event,callback);
+  }
+}
+function _IG_AdjustIFrameHeight() {
+}
+function _IG_Analytics() {
+}
+function _IG_RegisterOnloadHandler(handler) {
+	_IG_AddDOMEventHandler(window, "load", function(){handler();});
+}
+function _IG_RegisterMaximizeHandler(handler) {
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/prefs.js b/bundles/org.eclipse.e4.ui.gadgets/js/prefs.js
new file mode 100644
index 0000000..23c0722
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/prefs.js
@@ -0,0 +1,23 @@
+var gadgets = gadgets || {};
+
+gadgets.Prefs.prototype.set = function(key, value) {
+	this[key] = value;
+};
+gadgets.Prefs.prototype.getString = function(key) {
+	return this[key] || "";
+};
+gadgets.Prefs.prototype.getBool = function(key) {
+	return this[key] || true;
+};
+gadgets.Prefs.prototype.getInt = function(key) {
+	return 0 + this[key] || 0;
+};
+gadgets.Prefs.prototype.getMsg = function(key) {
+	return key;
+};
+gadgets.Prefs.prototype.getArray = function(key) {
+	return [];
+};
+
+//Alias for legacy code
+var _IG_Prefs = gadgets.Prefs;
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/util.js b/bundles/org.eclipse.e4.ui.gadgets/js/util.js
new file mode 100644
index 0000000..fb62a83
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/util.js
@@ -0,0 +1,18 @@
+var gadgets = gadgets || {};
+
+gadgets.util = function() {
+	return {
+		registerOnLoadHandler : function(callback) {
+			callback() ;
+			//window.onload = callback;
+		},
+	
+    	makeEnum : function (values) {
+			var obj = {};
+		    for (var i = 0, v; v = values[i]; ++i) {
+		    	obj[v] = v;
+		    }
+		    return obj;
+		}
+	}
+}();
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/window.js b/bundles/org.eclipse.e4.ui.gadgets/js/window.js
new file mode 100644
index 0000000..d62cb18
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/window.js
@@ -0,0 +1,11 @@
+var gadgets = gadgets || {};
+
+gadgets.window = gadgets.window || {};
+
+gadgets.window.setTitle = function(title) {
+  // TODO set the view's title
+};
+
+// Alias for legacy code
+var _IG_SetTitle = gadgets.window.setTitle;
+ 
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.gadgets/plugin.xml b/bundles/org.eclipse.e4.ui.gadgets/plugin.xml
new file mode 100644
index 0000000..95ebf49
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/plugin.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            allowMultiple="true"
+            class="org.eclipse.e4.ui.internal.gadgets.opensocial.OpenSocialView"
+            id="opensocial-demo.view"
+            name="Gadget"
+            restorable="true">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            defaultHandler="org.eclipse.e4.ui.internal.gadgets.opensocial.OpenGadgetHandler"
+            id="opensocialdemo.opengadget"
+            name="Open Gadget">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.propertyPages">
+      <page
+            class="org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages.MainPropertyPage"
+            id="org.eclipse.e4.ui.gadgets.Main"
+            name="Gadget">
+         <enabledWhen>
+            <adapt
+                  type="org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule">
+            </adapt>
+         </enabledWhen>
+      </page>
+      <page
+            category="org.eclipse.e4.ui.gadgets.Main"
+            class="org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages.OSGModulePrefsPropertyPage"
+            id="org.eclipse.e4.ui.gadgets.OSGModuleUserPreferences"
+            name="User Preferences">
+         <enabledWhen>
+            <adapt
+                  type="org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule">
+            </adapt>
+         </enabledWhen>
+      </page>
+   </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/pom.xml b/bundles/org.eclipse.e4.ui.gadgets/pom.xml
new file mode 100644
index 0000000..0029f4a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.eclipse.e4.ui</groupId>
+	<artifactId>org.eclipse.e4.ui.gadgets</artifactId>
+	<version>0.9.1-SNAPSHOT</version>
+	<packaging>eclipse-plugin</packaging>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.eclipse.e4.ui</groupId>
+			<artifactId>org.eclipse.e4.ui.web</artifactId>
+			<version>0.9.0-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+
+	<properties>
+		<tycho-version>0.11.1</tycho-version>
+	</properties>
+
+	<repositories>
+		<repository>
+			<id>helios</id>
+			<layout>p2</layout>
+			<url>http://download.eclipse.org/releases/helios</url>
+		</repository>
+		<repository>
+			<id>orbit</id>
+			<layout>p2</layout>
+			<url>http://download.eclipse.org/tools/orbit/downloads/drops/S20110422041657/repository/</url>
+		</repository>
+	</repositories>
+
+	<build>
+		<plugins>
+			<plugin>
+				<!-- TODO switch to org.eclipse.tycho when it will be publicly available -->
+				<groupId>org.sonatype.tycho</groupId>
+				<artifactId>tycho-maven-plugin</artifactId>
+				<version>${tycho-version}</version>
+				<extensions>true</extensions>
+			</plugin>
+			<plugin>
+				<groupId>org.sonatype.tycho</groupId>
+				<artifactId>target-platform-configuration</artifactId>
+				<version>${tycho-version}</version>
+				<configuration>
+					<resolver>p2</resolver>
+					<pomDependencies>consider</pomDependencies>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/LocaleKey.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/LocaleKey.java
new file mode 100644
index 0000000..b205191
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/LocaleKey.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+class LocaleKey {
+	String language;
+	String country;
+
+	public LocaleKey(String language, String country) {
+		this.language = language;
+		this.country = country;
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ ((country == null) ? 0 : country.hashCode());
+		result = prime * result
+				+ ((language == null) ? 0 : language.hashCode());
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		LocaleKey other = (LocaleKey) obj;
+		if (country == null) {
+			if (other.country != null)
+				return false;
+		} else if (!country.equals(other.country))
+			return false;
+		if (language == null) {
+			if (other.language != null)
+				return false;
+		} else if (!language.equals(other.language))
+			return false;
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGContent.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGContent.java
new file mode 100644
index 0000000..bf0ff40
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGContent.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+public class OSGContent {
+	String type;
+	String view;
+	String href;
+	String value;
+
+	public OSGContent(String type, String view, String href) {
+		this.type = type;
+		this.view = view == null ? "" : view;
+		this.href = href;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public String getView() {
+		return view;
+	}
+
+	public String getHref() {
+		return href;
+	}
+
+	public String getValue() {
+		return value;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGLocale.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGLocale.java
new file mode 100644
index 0000000..8601559
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGLocale.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class OSGLocale {
+	String lang;
+	String country;
+	String languageDirection;
+	String messagesURI;
+	Map<String, String> messages = new HashMap<String, String>();
+
+	public OSGLocale(String lang, String country, String languageDirection,
+			String messagesURI) {
+		this.lang = lang;
+		this.country = country;
+		this.languageDirection = languageDirection;
+		this.messagesURI = messagesURI;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGModule.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGModule.java
new file mode 100644
index 0000000..cd16c97
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGModule.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class OSGModule {
+	String title;
+	String author;
+	String description;
+	Map<LocaleKey, OSGLocale> locales = new HashMap<LocaleKey, OSGLocale>();
+	List<OSGUserPref> userPrefs = new ArrayList<OSGUserPref>();
+	Map<String, OSGContent> contents = new HashMap<String, OSGContent>();
+
+	public OSGModule(String title, String author, String description) {
+		this.title = title;
+		this.author = author;
+		this.description = description;
+	}
+
+	public String getAuthor() {
+		return author;
+	}
+
+	public Map<String, OSGContent> getContents() {
+		return contents;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public List<OSGUserPref> getUserPrefs() {
+		return userPrefs;
+	}
+
+	public void setUserPrefValue(String key, String value) {
+		for (OSGUserPref pref : getUserPrefs()) {
+			if (pref.getName().equals(key)) {
+				pref.setValue((String) value);
+			}
+		}
+	}
+
+	public String getUserPrefValue(String key) {
+		for (OSGUserPref pref : getUserPrefs()) {
+			if (pref.getName().equals(key))
+				return (pref.getValue() == null) ? "" : pref.getValue();
+		}
+		return null;
+	}
+
+	public String getUserPrefDefaultValue(String key) {
+		for (OSGUserPref pref : getUserPrefs()) {
+			if (pref.getName().equals(key))
+				return (pref.getDefaultValue() == null) ? "" : pref.getValue();
+		}
+		return null;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGUserPref.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGUserPref.java
new file mode 100644
index 0000000..fe451bc
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGUserPref.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+public class OSGUserPref {
+	String name;
+	String value;
+	String defaultValue;
+
+	public OSGUserPref(String name, String defaultValue) {
+		this.name = name;
+		this.value = defaultValue;
+		this.defaultValue = defaultValue;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	public String getDefaultValue() {
+		return defaultValue;
+	}
+
+	@Override
+	public String toString() {
+		return "OSGUserPref [name=" + name + ", value=" + value
+				+ ", defaultValue=" + defaultValue + "]";
+	}
+	
+	
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenGadgetHandler.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenGadgetHandler.java
new file mode 100644
index 0000000..562ff04
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenGadgetHandler.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+public class OpenGadgetHandler extends AbstractHandler {
+
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		IWorkbenchWindow wwin = HandlerUtil
+				.getActiveWorkbenchWindowChecked(event);
+		ISelection selection = HandlerUtil.getCurrentSelection(event);
+		String selectedText = "";
+		if (selection != null) {
+			Method getText;
+			try {
+				getText = selection.getClass().getMethod("getText");
+				selectedText = (String) getText.invoke(selection);
+			} catch (Exception e) {
+			}
+		}
+		InputDialog inputDialog = new InputDialog(wwin.getShell(),
+				"Open Gadget", "Please enter the gadget URL.", selectedText,
+				null);
+		if (inputDialog.open() == Dialog.OK) {
+			try {
+				String url = inputDialog.getValue();
+				url = url.replace(":", "%3A");
+				wwin.getActivePage().showView("opensocial-demo.view", url,
+						IWorkbenchPage.VIEW_ACTIVATE);
+			} catch (PartInitException e) {
+				StatusManager.getManager().handle(
+						new Status(IStatus.ERROR, "e4.opensocial",
+								"Could not open gadget", e));
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialUtil.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialUtil.java
new file mode 100644
index 0000000..ed07ef7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialUtil.java
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class OpenSocialUtil {
+
+	private static int moduleId = 0;
+
+	public static OSGModule loadModule(String uriString) {
+		java.net.URI uri;
+		OSGModule module;
+		try {
+			uri = new java.net.URI(uriString);
+			module = parseModuleXML(uri);
+		} catch (Exception e) {
+			throw new RuntimeException("Could not load module", e);
+		}
+		OSGLocale locale = determineLocale(module);
+
+		Map<String, String> hangmanMap = new HashMap<String, String>();
+		hangmanMap.put("__MODULE_ID__", String.valueOf(moduleId++));
+		hangmanMap.put("__ENV_google_apps_auth_path__", "render#");
+
+		populateHangmanMapFromLocale(hangmanMap, locale, uri);
+		populateHangmanMapFromUserPrefs(hangmanMap, module.userPrefs);
+
+		module.title = hangmanExpand(module.title, hangmanMap);
+		module.description = hangmanExpand(module.description, hangmanMap);
+		module.author = hangmanExpand(module.author, hangmanMap);
+
+		// System.out.println("Gadget: " + module.title);
+		// System.out.println("Author: " + module.author);
+		// System.out.println("Description: " + module.description);
+
+		for (OSGContent content : new HashSet<OSGContent>(module.contents
+				.values())) {
+			if ("url".equalsIgnoreCase(content.type)) {
+				content.href = hangmanExpand(content.href, hangmanMap);
+				// System.out.println("URL: " + content.href);
+			} else if ("html".equalsIgnoreCase(content.type)) {
+				content.value = hangmanExpand(content.value, hangmanMap);
+				// System.out.println("HTML: ...");
+			} else {
+				// System.out.println("unhandled type: " + content.type);
+			}
+			// System.out.println("Views: " + content.view);
+		}
+		return module;
+	}
+
+	private static void populateHangmanMapFromUserPrefs(
+			Map<String, String> hangmanMap, List<OSGUserPref> userPrefs) {
+		for (OSGUserPref pref : userPrefs) {
+			hangmanMap.put("__UP_" + pref.name + "__", pref.defaultValue);
+		}
+	}
+
+	private static void populateHangmanMapFromLocale(
+			Map<String, String> hangmanMap, OSGLocale locale, java.net.URI uri) {
+		hangmanMap.put("__BIDI_START_EDGE__", "left");
+		hangmanMap.put("__BIDI_END_EDGE__", "right");
+		hangmanMap.put("__BIDI_DIR__", "ltr");
+		hangmanMap.put("__BIDI_REVERSE_DIR__", "rtl");
+		if (locale != null) {
+			if ("rtl".equals(locale.languageDirection)) {
+				hangmanMap.put("__BIDI_START_EDGE__", "right");
+				hangmanMap.put("__BIDI_END_EDGE__", "left");
+				hangmanMap.put("__BIDI_DIR__", "rtl");
+				hangmanMap.put("__BIDI_REVERSE_DIR__", "ltr");
+			}
+			String messagesURIString = locale.messagesURI;
+			if (messagesURIString != null) {
+				if (!messagesURIString.startsWith("http")) {
+					if (!messagesURIString.startsWith("/")) {
+						String uriString = uri.toString();
+						messagesURIString = uriString.substring(0, uriString
+								.lastIndexOf('/'))
+								+ "/" + messagesURIString;
+					} else {
+						messagesURIString = "http://" + uri.getHost()
+								+ messagesURIString;
+					}
+				}
+				try {
+					addMessagesToMap(hangmanMap, messagesURIString);
+				} catch (Exception e) {
+					throw new RuntimeException("Could not parse messages", e);
+				}
+			} else {
+				addMessagesToMap(hangmanMap, locale.messages);
+			}
+		}
+	}
+
+	private static OSGLocale determineLocale(OSGModule module) {
+		OSGLocale locale = module.locales.get(new LocaleKey(System
+				.getProperty("osgi.nl"), System.getProperty("user.country")));
+		if (locale == null) {
+			locale = module.locales.get(new LocaleKey(System
+					.getProperty("user.language"), System
+					.getProperty("user.country")));
+		}
+		if (locale == null) {
+			locale = module.locales.get(new LocaleKey(System
+					.getProperty("osgi.nl"), null));
+		}
+		if (locale == null) {
+			locale = module.locales.get(new LocaleKey(System
+					.getProperty("user.language"), null));
+		}
+		if (locale == null) {
+			locale = module.locales.get(new LocaleKey(null, System
+					.getProperty("user.country")));
+		}
+		if (locale == null) {
+			locale = module.locales.get(new LocaleKey(null, null));
+		}
+		return locale;
+	}
+
+	private static OSGModule parseModuleXML(java.net.URI uri) throws Exception {
+		final OSGModule[] result = { null };
+		parseXML(uri, new DefaultHandler() {
+			OSGModule module;
+			OSGContent content;
+			StringBuffer contentBuffer;
+			OSGLocale locale;
+			String currentMsgName = null;
+			StringBuffer currentMsgValue = null;
+
+			public void startElement(String uri, String localName,
+					String qName, Attributes attributes) throws SAXException {
+				if (contentBuffer != null) {
+					contentBuffer.append("<" + qName);
+					for (int i = 0; i < attributes.getLength(); i++) {
+						contentBuffer.append(" " + attributes.getQName(i)
+								+ "=\"" + attributes.getValue(i) + "\"");
+					}
+					contentBuffer.append(">");
+				} else if ("ModulePrefs".equalsIgnoreCase(qName)) {
+					module = new OSGModule(attributes.getValue("title"),
+							attributes.getValue("author"), attributes
+									.getValue("description"));
+					result[0] = module;
+				} else if ("Locale".equalsIgnoreCase(qName)) {
+					locale = new OSGLocale(attributes.getValue("lang"),
+							attributes.getValue("country"), attributes
+									.getValue("language_direction"), attributes
+									.getValue("messages"));
+					module.locales.put(new LocaleKey(locale.lang,
+							locale.country), locale);
+				} else if ("msg".equalsIgnoreCase(qName)) {
+					currentMsgName = attributes.getValue("name");
+					currentMsgValue = new StringBuffer();
+				} else if ("UserPref".equalsIgnoreCase(qName)) {
+					module.userPrefs.add(new OSGUserPref(attributes
+							.getValue("name"), attributes
+							.getValue("default_value")));
+				} else if ("Content".equalsIgnoreCase(qName)) {
+					content = new OSGContent(attributes.getValue("type"),
+							attributes.getValue("view"), attributes
+									.getValue("href"));
+					contentBuffer = new StringBuffer();
+				}
+			}
+
+			public void characters(char[] ch, int start, int length)
+					throws SAXException {
+				if (contentBuffer != null) {
+					contentBuffer.append(ch, start, length);
+				}
+				if (currentMsgName != null) {
+					currentMsgValue.append(ch, start, length);
+				}
+			}
+
+			public void endElement(String uri, String localName, String qName)
+					throws SAXException {
+				if ("Content".equalsIgnoreCase(qName) && content != null
+						&& contentBuffer != null) {
+					content.value = contentBuffer.toString();
+					StringTokenizer t = new StringTokenizer(content.view, ",");
+					if (!t.hasMoreTokens()) {
+						module.contents.put("default", content);
+					} else
+						while (t.hasMoreTokens()) {
+							module.contents.put(t.nextToken(), content);
+						}
+					contentBuffer = null;
+				} else if ("Locale".equalsIgnoreCase(qName)) {
+					locale = null;
+				} else if ("msg".equalsIgnoreCase(qName)) {
+					locale.messages.put(currentMsgName, currentMsgValue
+							.toString());
+					currentMsgName = null;
+				} else if (contentBuffer != null) {
+					contentBuffer.append("</" + qName);
+					contentBuffer.append(">");
+				}
+				content = null;
+			}
+		});
+		return result[0];
+	}
+
+	private static void addMessagesToMap(final Map<String, String> hangmanMap,
+			String messagesURIString) throws Exception {
+		// System.out.println("Loading message bundle from: " +
+		// messagesURIString);
+		DefaultHandler handler = new DefaultHandler() {
+			String name;
+			String value;
+
+			public void startElement(String uri, String localName,
+					String qName, Attributes attributes) throws SAXException {
+				name = attributes.getValue("name");
+			}
+
+			public void characters(char[] ch, int start, int length)
+					throws SAXException {
+				value = new String(ch, start, length);
+			}
+
+			public void endElement(String uri, String localName, String qName)
+					throws SAXException {
+				if ("msg".equalsIgnoreCase(qName) && name != null
+						&& value != null) {
+					hangmanMap.put("__MSG_" + name + "__", value);
+				}
+			}
+		};
+		parseXML(new java.net.URI(messagesURIString), handler);
+	}
+
+	private static void addMessagesToMap(Map<String, String> hangmanMap,
+			Map<String, String> messages) {
+		for (Map.Entry<String, String> entry : messages.entrySet()) {
+			hangmanMap.put("__MSG_" + entry.getKey() + "__", entry.getValue());
+		}
+	}
+
+	private static void parseXML(java.net.URI uri, DefaultHandler handler)
+			throws MalformedURLException, IOException,
+			ParserConfigurationException, SAXException {
+		URL messagesURL = uri.toURL();
+		URLConnection connection = messagesURL.openConnection();
+		String encoding = connection.getContentEncoding();
+		if (encoding == null) {
+			String contentType = connection.getHeaderField("Content-Type");
+			int charsetIndex;
+			if (contentType != null
+					&& (charsetIndex = contentType.indexOf("charset=")) != -1) {
+				int charsetBegin = charsetIndex + "charset=".length();
+				int charsetEnd = charsetBegin;
+				while (contentType.length() > charsetEnd
+						&& " ,;".indexOf(contentType.charAt(charsetEnd)) == -1) {
+					charsetEnd++;
+				}
+				if (charsetEnd > charsetBegin) {
+					encoding = contentType.substring(charsetBegin, charsetEnd);
+				}
+			}
+		}
+		InputStream is = connection.getInputStream();
+		try {
+			SAXParserFactory spf = SAXParserFactory.newInstance();
+			SAXParser parser = spf.newSAXParser();
+			InputSource source = new InputSource(is);
+			if (encoding != null) {
+				source.setEncoding(encoding);
+			}
+			parser.parse(source, handler);
+		} finally {
+			is.close();
+		}
+	}
+
+	private static String hangmanExpand(String s, Map<String, String> hangmanMap) {
+		if (s == null) {
+			return null;
+		}
+		StringBuffer result = new StringBuffer(s.length());
+		int currentIndex = 0;
+		int indexOfUnderscores;
+		while ((indexOfUnderscores = s.indexOf("__", currentIndex)) != -1) {
+			result.append(s.substring(currentIndex, indexOfUnderscores));
+			int indexOfNextUnderscores = s
+					.indexOf("__", indexOfUnderscores + 2);
+			if (indexOfNextUnderscores != -1) {
+				String key = s.substring(indexOfUnderscores,
+						indexOfNextUnderscores + 2);
+				String value = hangmanMap.get(key);
+				if (value != null) {
+					result.append(value);
+				} else {
+					result.append(key);
+				}
+				currentIndex = indexOfNextUnderscores + 2;
+			} else {
+				result.append("__");
+				currentIndex = indexOfUnderscores + 2;
+			}
+		}
+		result.append(s.substring(currentIndex));
+		return result.toString();
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialView.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialView.java
new file mode 100644
index 0000000..1c2cd47
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialView.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *     Benjamin Cabe, Sierra Wireless - ongoing improvements
+ *     Sebastien Moran, Sierra Wireless - bug 298291
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.ui.internal.gadgets.opensocial.browserfunctions.MakeXmlHttpRequest;
+import org.eclipse.e4.ui.web.BrowserViewPart;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class OpenSocialView extends BrowserViewPart implements
+		IResourceChangeListener {
+
+	public static final String NO_HEADER_VALUE = "undefined";
+
+	public static final String HEADER_NAME_VALUE_SEPARATOR = "#";
+
+	public static final String HEADERS_SEPARATOR = "\n";
+
+	public static final String GET_METHOD = "GET";
+
+	public static final String USERPREFS = "userprefs";
+
+	private String url;
+	private String html;
+	private OSGModule module;
+	private IMemento memento;
+	private final String[] scripts = new String[] { "util.js", "io.js",
+			"misc.js", "prefs.js", "window.js" }; // util.js must always be
+	// loaded first
+	private Bundle bundle;
+	private Action editPropertiesAction;
+	private Action refreshAction;
+
+	private IFile moduleFile;
+
+	private BrowserFunction makeRequestBrowserFunction;
+
+	protected String getNewWindowViewId() {
+		return getSite().getId();
+	}
+
+	@Override
+	public void init(IViewSite site, IMemento memento) throws PartInitException {
+		super.init(site, memento);
+		url = site.getSecondaryId();
+		this.memento = memento;
+		bundle = FrameworkUtil.getBundle(this.getClass());
+
+		url = url.replace("%3A", ":");
+		URI uri = URI.create(url);
+		if (!uri.isAbsolute())
+			return;
+		IFile[] files = ResourcesPlugin.getWorkspace().getRoot()
+				.findFilesForLocationURI(uri);
+		if (files.length > 0) {
+			moduleFile = files[0];
+			moduleFile.getWorkspace().addResourceChangeListener(this,
+					IResourceChangeEvent.POST_CHANGE);
+		}
+	}
+
+	@Override
+	public void createPartControl(Composite parent) {
+		super.createPartControl(parent);
+		makeActions();
+		contributeToActionBars();
+		contributeToToolBars();
+	}
+
+	private void makeActions() {
+		editPropertiesAction = new Action() {
+			public void run() {
+				new PropertyDialogAction(getSite(), new ISelectionProvider() {
+					public void setSelection(ISelection selection) {
+					}
+
+					public void removeSelectionChangedListener(
+							ISelectionChangedListener listener) {
+					}
+
+					public ISelection getSelection() {
+						return new StructuredSelection(module);
+					}
+
+					public void addSelectionChangedListener(
+							ISelectionChangedListener listener) {
+					}
+				}).createDialog().open();
+				configureBrowser(browser);
+			}
+		};
+		editPropertiesAction.setText("Module settings");
+		editPropertiesAction.setToolTipText("Edit Module Settings");
+
+		refreshAction = new Action() {
+			public void run() {
+				module = null;
+				configureBrowser(browser);
+			}
+		};
+		refreshAction.setText("Refresh");
+		refreshAction.setDisabledImageDescriptor(ImageDescriptor
+				.createFromURL(bundle
+						.getEntry("/icons/full/dlcl16/refresh.gif")));
+		refreshAction.setImageDescriptor(ImageDescriptor.createFromURL(bundle
+				.getEntry("/icons/full/elcl16/refresh.gif")));
+		refreshAction.setToolTipText("Refresh module");
+	}
+
+	private void contributeToActionBars() {
+		IActionBars bars = getViewSite().getActionBars();
+		bars.getMenuManager().add(editPropertiesAction);
+		bars.getMenuManager().update(true);
+	}
+
+	private void contributeToToolBars() {
+		IActionBars bars = getViewSite().getActionBars();
+		bars.getToolBarManager().add(refreshAction);
+		bars.getToolBarManager().update(true);
+	}
+
+	private void registerBrowserFunctions() {
+		if (makeRequestBrowserFunction != null)
+			makeRequestBrowserFunction.dispose();
+
+		makeRequestBrowserFunction = new MakeXmlHttpRequest(browser);
+	}
+
+	@Override
+	public void dispose() {
+		if (moduleFile != null)
+			moduleFile.getWorkspace().removeResourceChangeListener(this);
+		if (makeRequestBrowserFunction != null)
+			makeRequestBrowserFunction.dispose();
+		super.dispose();
+	}
+
+	@Override
+	public void saveState(IMemento memento) {
+		saveUserPreferences(memento);
+	}
+
+	private void saveUserPreferences(IMemento memento) {
+		IMemento node = memento.createChild(USERPREFS);
+		for (OSGUserPref pref : module.getUserPrefs()) {
+			node.putString(pref.getName(), pref.getValue());
+		}
+	}
+
+	protected void configureBrowser(Browser browser) {
+		registerBrowserFunctions();
+
+		String localUrl = null;
+		if (url != null) {
+			url = url.replace("%3A", ":");
+			final String uriForIcon = url;
+			if (module == null) {
+				module = OpenSocialUtil.loadModule(url);
+				loadUserPreferences(module, memento);
+			}
+			setPartName(module.getTitle());
+			setTitleToolTip(module.getDescription());
+			Map<String, OSGContent> contents = module.getContents();
+			OSGContent content = contents.get("home");
+			if (content == null) {
+				content = contents.get("default");
+			}
+			if (content == null) {
+				content = contents.get("canvas");
+			}
+			if (content == null) {
+				content = contents.get("");
+			}
+			if ("url".equalsIgnoreCase(content.getType())) {
+				localUrl = content.getHref();
+			} else if ("html".equalsIgnoreCase(content.getType())) {
+				StringBuilder igFunctions = new StringBuilder();
+				igFunctions.append("<head></head><script>\r\n");
+				igFunctions.append("var gadgets = gadgets || {};\r\n");
+				igFunctions.append("gadgets.Prefs = function() {\r\n");
+				for (OSGUserPref userPref : module.getUserPrefs()) {
+					igFunctions.append("this." + userPref.getName());
+					igFunctions.append("='");
+					igFunctions.append(userPref.getValue());
+					igFunctions.append("';");
+				}
+				igFunctions.append("\r\n}\r\n\r\n");
+				try {
+					// inject Javascript gadgets.* functions
+					for (String script : scripts) {
+						// append the script to igFunctions
+						InputStream scriptInputStream = bundle.getEntry(
+								"js/" + script).openStream();
+						BufferedReader scriptReader = new BufferedReader(
+								new InputStreamReader(scriptInputStream));
+						String line = null;
+						while ((line = scriptReader.readLine()) != null) {
+							igFunctions.append(line + "\r\n");
+						}
+						scriptReader.close();
+					}
+				} catch (IOException e) {
+					// TODO log
+				}
+				igFunctions.append("\r\n</script>\r\n");
+				html = igFunctions.toString() + content.getValue();
+			}
+			if (localUrl == null && html == null) {
+				throw new RuntimeException("could not find Gadget URL");
+			} else if (uriForIcon != null) {
+				Job job = new Job("Retrieve Icon for " + module.getTitle()) {
+
+					@Override
+					protected IStatus run(IProgressMonitor monitor) {
+						URI uri;
+						try {
+							uri = new URI(uriForIcon);
+						} catch (URISyntaxException e1) {
+							return Status.CANCEL_STATUS;
+						}
+						String host = uri.getHost();
+						try {
+							URL favicon = new URL("http://" + host
+									+ "/favicon.ico");
+							InputStream is = favicon.openConnection()
+									.getInputStream();
+							Display display = getSite().getWorkbenchWindow()
+									.getShell().getDisplay();
+							final Image icon = new Image(display, is);
+							display.asyncExec(new Runnable() {
+
+								public void run() {
+									setTitleImage(icon);
+								}
+							});
+						} catch (MalformedURLException e) {
+							return Status.CANCEL_STATUS;
+						} catch (IOException e) {
+							return Status.CANCEL_STATUS;
+						} catch (SWTException e) {
+							// the Image might be malformed or not readable by
+							// SWT
+							return Status.CANCEL_STATUS;
+						}
+						return Status.OK_STATUS;
+					}
+				};
+				job.schedule();
+			}
+		} else {
+			localUrl = "http://ig.gmodules.com/gadgets/ifr?view=home&url="
+					+ "http://hosting.gmodules.com/ig/gadgets/file/104276582316790234013/test-1.xml"
+					+ "&nocache=0&up_feed=http://picasaweb.google.com/data/feed/base/user/picasateam/albumid/5114659638793351217%3Fkind%3Dphoto%26alt%3Drss%26hl%3Den_US&up_title=My+Picasa+Photos&up_gallery=&up_desc=1&lang=en&country=us&.lang=en&.country=us&synd=ig&mid=110&ifpctok=-6064860744303900509&exp_split_js=1&exp_track_js=1&exp_ids=17259,300668&parent=http://www.google.com&refresh=3600&libs=core:core.io:core.iglegacy&extern_js=/extern_js/f/CgJlbhICdXMrMNIBOAEs/SH2Zv0WBdfQ.js&is_signedin=1";
+		}
+		if (html != null) {
+			browser.setText(html);
+		}
+		if (localUrl != null) {
+			browser.setUrl(localUrl);
+		}
+
+	}
+
+	private void loadUserPreferences(OSGModule module, IMemento memento) {
+		if (memento == null)
+			return;
+
+		IMemento node = memento.getChild(USERPREFS);
+		if (node == null)
+			return;
+
+		for (String key : node.getAttributeKeys()) {
+			for (OSGUserPref pref : module.getUserPrefs()) {
+				if (pref.getName().equals(key))
+					pref.setValue(node.getString(key));
+			}
+		}
+	}
+
+	public void resourceChanged(IResourceChangeEvent event) {
+		IResourceDelta rootDelta = event.getDelta();
+		if (rootDelta.findMember(moduleFile.getFullPath()) == null)
+			return;
+
+		try {
+			event.getDelta().accept(new IResourceDeltaVisitor() {
+				public boolean visit(IResourceDelta delta) throws CoreException {
+					if (delta.getResource() instanceof IContainer)
+						return true;
+
+					if (moduleFile.equals(delta.getResource())) {
+						if (delta.getKind() == IResourceDelta.REMOVED) {
+							Display.getDefault().asyncExec(new Runnable() {
+								public void run() {
+									getViewSite().getPage().hideView(
+											OpenSocialView.this);
+								}
+							});
+						} else {
+							module = null;
+							configureBrowser(browser);
+						}
+					}
+					return false;
+				}
+			});
+		} catch (CoreException e) {
+			// TODO log correctly
+		}
+
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/browserfunctions/MakeXmlHttpRequest.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/browserfunctions/MakeXmlHttpRequest.java
new file mode 100644
index 0000000..b1198ee
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/browserfunctions/MakeXmlHttpRequest.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Sierra Wireless 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 which accompanies this
+ * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: Benjamin Cabe, Sierra Wireless - initial API and implementation
+ * Sebastien Moran, Sierra Wireless - bug 298291
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial.browserfunctions;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OpenSocialView;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.widgets.Display;
+
+public final class MakeXmlHttpRequest extends BrowserFunction {
+	public MakeXmlHttpRequest(Browser browser) {
+		super(browser, "e4_makeXmlHttpRequest");
+	}
+
+	@Override
+	public Object function(Object[] arguments) {
+		/*
+		 * e4_makeXmlHttpRequest : function(url, callback, method, contentType,
+		 * headers, postData)
+		 */
+		try {
+			// Retrieve arguments
+			String url = (String) arguments[0];
+			String callback = (String) arguments[1];
+			String method = (String) arguments[2];
+			String contentType = (String) arguments[3];
+			// headers format :
+			// headerName#headerValue\nheader2Name#header2Value
+			String headers = (String) arguments[4];
+			String postData = (String) arguments[5];
+
+			HttpClient httpClient = new HttpClient();
+			// Create GET or POST http method
+			HttpMethod httpMethod = createMethod(url, method);
+
+			// Add needed headers
+			if (!"".equals(headers))
+				addHeaders(httpMethod, headers);
+
+			// Handle PostData if needed
+			if (postData != null) {
+				((PostMethod) httpMethod)
+						.setRequestEntity(new StringRequestEntity(postData,
+								"text/xml", "utf-8"));
+			}
+
+			int status = httpClient.executeMethod(httpMethod);
+
+			String responseBodyAsString = retrieveResponseBody(httpMethod);
+
+			// FIXME: at the moment, remove single quotes causing js
+			// problems.
+			responseBodyAsString = responseBodyAsString.replaceAll("'", " ");
+
+			String responseScript = "\n";
+			// Create and fill response object
+			responseScript += "var response = new Object();\n";
+			responseScript += "response.rc=" + status + ";\n";
+			responseScript += "response.text='" + responseBodyAsString + "';\n";
+
+			// Create the response's data property
+			if ("DOM".equals(contentType)) {
+				responseScript = createDOMResponseData(responseScript);
+			} else if ("JSON".equals(contentType)) {
+				responseScript = createJSONResponseData(responseBodyAsString,
+						responseScript);
+			} else if ("TEXT".equals(contentType)) {
+				responseScript = createTEXTReponseData(responseScript);
+			} else if ("FEED".equals(contentType)) {
+				// FIXME : Not implemented for the moment.
+				responseScript = createFEEDResponseData(responseScript);
+			}
+
+			// Instanciate and call callback
+			responseScript += "var callback = " + callback + ";\n"
+					+ "callback(response);\n";
+
+			final String script = responseScript;
+			Display.getDefault().asyncExec(new Runnable() {
+				public void run() {
+					getBrowser().execute(script);
+				}
+			});
+			return status;
+		} catch (HttpException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		return HttpStatus.SC_INTERNAL_SERVER_ERROR;
+	}
+
+	/**
+	 * TODO : Create a JSON representation of the RSS XML data
+	 * 
+	 * @param responseScript
+	 *            String
+	 */
+	protected String createFEEDResponseData(String responseScript) {
+		responseScript += "response.data='Not implemented';";
+		return responseScript;
+	}
+
+	/**
+	 * TEXT data corresponds to the raw response text
+	 * 
+	 * @param responseScript
+	 *            String
+	 */
+	protected String createTEXTReponseData(String responseScript) {
+		responseScript += "response.data=response.text;";
+		return responseScript;
+	}
+
+	/**
+	 * Create the JSON Object
+	 * 
+	 * @param responseBodyAsString
+	 *            String, raw response body
+	 * @param responseScript
+	 *            String
+	 */
+	protected String createJSONResponseData(String responseBodyAsString,
+			String responseScript) {
+		// Parse response body to create the corresponding JSON
+		// object
+		responseScript += "response.data=eval('(" + responseBodyAsString
+				+ ")')\n";
+		return responseScript;
+	}
+
+	/**
+	 * Parse the XML response body to create the corresponding DOM.
+	 * 
+	 * @param responseScript
+	 *            String
+	 */
+	protected String createDOMResponseData(String responseScript) {
+		// Parse response body to create the corresponding DOM
+		// object
+		responseScript += "var xmlDoc;\n";
+		responseScript += "if (window.DOMParser){\n"
+				+ "parser=new DOMParser();\n"
+				+ "xmlDoc=parser.parseFromString(response.text,'text/xml');\n"
+				+ "} else {\n// Internet Explorer\n"
+				+ "xmlDoc=new ActiveXObject('Microsoft.XMLDOM');\n"
+				+ "xmlDoc.async='false';\n"
+				+ "xmlDoc.loadXML(response.text);\n" + "}\n";
+		responseScript += "response.data=xmlDoc;\n";
+		return responseScript;
+	}
+
+	protected String retrieveResponseBody(HttpMethod httpMethod)
+			throws IOException, UnsupportedEncodingException {
+
+		String responseBodyAsString = "";
+		InputStream bodyAsStream = httpMethod.getResponseBodyAsStream();
+
+		StringBuilder sb = new StringBuilder();
+		String line;
+		try {
+			BufferedReader reader = new BufferedReader(new InputStreamReader(
+					bodyAsStream, "UTF-8"));
+			while ((line = reader.readLine()) != null) {
+				sb.append(line);
+			}
+		} finally {
+			bodyAsStream.close();
+		}
+
+		responseBodyAsString = sb.toString();
+		return responseBodyAsString;
+	}
+
+	/**
+	 * Parse the String corresponding the headers and add them to the HttpMethod
+	 * 
+	 * @param httpMethod
+	 *            HttpMethod which will be filled with the given headers
+	 * @param headers
+	 *            String representation of the headers to add. They respect the
+	 *            following format :
+	 *            headerName#headerValue>header2Name#header2Value
+	 * 
+	 */
+	private void addHeaders(HttpMethod httpMethod, String headers) {
+		// Split to retrieve all headers
+		String[] splittedHeader = headers
+				.split(OpenSocialView.HEADERS_SEPARATOR);
+
+		// Loop through the headers
+		for (String header : splittedHeader) {
+			// Split to retrieve the header name & value
+			String[] headerNameAndValue = header
+					.split(OpenSocialView.HEADER_NAME_VALUE_SEPARATOR);
+			String name = headerNameAndValue[0];
+			String value = headerNameAndValue[1];
+			// If the value exists add it to the
+			// HttpMethod
+			if (!OpenSocialView.NO_HEADER_VALUE.equals(value))
+				httpMethod.addRequestHeader(name, value);
+		}
+	}
+
+	/**
+	 * 
+	 * @param url
+	 * @param method
+	 * @return
+	 */
+	protected HttpMethod createMethod(String url, String method) {
+		if (OpenSocialView.GET_METHOD.equals(method))
+			return new GetMethod(url);
+
+		return new PostMethod(url);
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/MainPropertyPage.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/MainPropertyPage.java
new file mode 100644
index 0000000..aa03bec
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/MainPropertyPage.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Sierra Wireless 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Benjamin Cabe, Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages;
+
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+public class MainPropertyPage extends PropertyPage implements
+		IWorkbenchPropertyPage {
+
+	public MainPropertyPage() {
+		// TODO Auto-generated constructor stub
+	}
+
+	@Override
+	protected Control createContents(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout(2, false);
+		composite.setLayout(layout);
+		GridData data = new GridData(GridData.FILL);
+		data.grabExcessHorizontalSpace = true;
+		composite.setLayoutData(data);
+
+		OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+		addProperty(composite, "Title:", module.getTitle());
+		addProperty(composite, "Author:", module.getAuthor());
+		addProperty(composite, "Description:", module.getDescription());
+
+		return composite;
+	}
+
+	private void addProperty(Composite parent, String name, String value) {
+		Label label = new Label(parent, SWT.NULL);
+		label.setText(name);
+
+		Text text = new Text(parent, SWT.READ_ONLY);
+		if (value == null)
+			value = "";
+		text.setText(value.trim());
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		text.setLayoutData(gd);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/OSGModulePrefsPropertyPage.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/OSGModulePrefsPropertyPage.java
new file mode 100644
index 0000000..d371f3a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/OSGModulePrefsPropertyPage.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Sierra Wireless 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Benjamin Cabe, Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule;
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OSGUserPref;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+public class OSGModulePrefsPropertyPage extends PropertyPage implements
+		IWorkbenchPropertyPage {
+
+	private Map<String, Text> preferenceEditors = new HashMap<String, Text>();
+
+	public OSGModulePrefsPropertyPage() {
+		// TODO Auto-generated constructor stub
+	}
+
+	@Override
+	protected Control createContents(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout(2, false);
+		composite.setLayout(layout);
+		GridData data = new GridData(GridData.FILL);
+		data.grabExcessHorizontalSpace = true;
+		composite.setLayoutData(data);
+
+		OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+		for (OSGUserPref pref : module.getUserPrefs()) {
+			addProperty(composite, pref.getName(), pref.getValue());
+		}
+
+		return composite;
+	}
+
+	@Override
+	public boolean performOk() {
+		OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+		for (Map.Entry<String, Text> entry : preferenceEditors.entrySet()) {
+			module.setUserPrefValue(entry.getKey(), entry.getValue().getText());
+		}
+
+		return true;
+	}
+
+	@Override
+	protected void performDefaults() {
+		OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+		for (Map.Entry<String, Text> entry : preferenceEditors.entrySet()) {
+			String userPrefDefaultValue = module.getUserPrefDefaultValue(entry
+					.getKey());
+			entry.getValue().setText(userPrefDefaultValue);
+		}
+	}
+
+	private void addProperty(Composite parent, String key, String value) {
+		Label label = new Label(parent, SWT.NULL);
+		label.setText(key);
+
+		Text text = new Text(parent, SWT.BORDER);
+		if (value == null)
+			value = "";
+		text.setText(value);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		text.setLayoutData(gd);
+		preferenceEditors.put(key, text);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/.classpath b/bundles/org.eclipse.e4.ui.selection/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.selection/.project b/bundles/org.eclipse.e4.ui.selection/.project
new file mode 100644
index 0000000..2e6f00f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.selection</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.core.prefs
new file mode 100755
index 0000000..081f9c7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,365 @@
+#Tue Jun 23 16:26:13 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=100
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=100
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.ui.prefs
new file mode 100755
index 0000000..fd71409
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,118 @@
+#Thu Jun 18 15:40:58 EDT 2009
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_trailing_whitespaces=false
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Eclipse long lines
+formatter_settings_version=11
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************\n * Copyright (c) ${year} IBM Corporation and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n *     IBM Corporation - initial API and implementation\n ******************************************************************************/\n</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.pde.core.prefs
new file mode 100755
index 0000000..d237e73
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 24 16:23:03 EDT 2008
+eclipse.preferences.version=1
+pluginProject.extensions=true
+resolve.requirebundle=false
diff --git a/bundles/org.eclipse.e4.ui.selection/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.selection/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..821f400
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Context Selection Provider
+Bundle-SymbolicName: org.eclipse.e4.ui.selection;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.e4.ui.selection.internal.Activator
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.e4.core.services.context,
+ org.eclipse.e4.core.services.context.spi,
+ org.osgi.framework;version="1.5.0"
+Service-Component: OSGI-INF/selectionService.xml, OSGI-INF/selectionLookup.xml
+Export-Package: org.eclipse.e4.ui.selection,
+ org.eclipse.e4.ui.selection.internal
diff --git a/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionLookup.xml b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionLookup.xml
new file mode 100644
index 0000000..0f9033e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionLookup.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.ui.selection.lookUp">
+   <implementation class="org.eclipse.e4.ui.selection.internal.SelectionLookupFunction"/>
+   <service>
+      <provide interface="org.eclipse.e4.core.services.context.IContextFunction"/>
+   </service>
+   <property name="service.context.key" type="String" value="selection"/>
+</scr:component>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionService.xml b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionService.xml
new file mode 100644
index 0000000..64570b7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionService.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.ui.selection.ESelectionService">
+   <implementation class="org.eclipse.e4.ui.selection.internal.SelectionServiceCreationFunction"/>
+   <service>
+      <provide interface="org.eclipse.e4.core.services.context.IContextFunction"/>
+   </service>
+   <property name="service.context.key" type="String" value="org.eclipse.e4.ui.selection.ESelectionService"/>
+</scr:component>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.selection/build.properties b/bundles/org.eclipse.e4.ui.selection/build.properties
new file mode 100644
index 0000000..6210e84
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               OSGI-INF/
+source.. = src/
diff --git a/bundles/org.eclipse.e4.ui.selection/selection.psf b/bundles/org.eclipse.e4.ui.selection/selection.psf
new file mode 100755
index 0000000..19f0b3d
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/selection.psf
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<psf version="2.0">
+<provider id="org.eclipse.team.cvs.core.cvsnature">
+<project reference="1.0,:pserver:dev.eclipse.org:/cvsroot/eclipse,e4/org.eclipse.e4.ui/bundles/org.eclipse.e4.ui.selection,org.eclipse.e4.ui.selection"/>
+<project reference="1.0,:pserver:dev.eclipse.org:/cvsroot/eclipse,e4/org.eclipse.e4.ui/tests/org.eclipse.e4.ui.selection.tests,org.eclipse.e4.ui.selection.tests"/>
+</provider>
+</psf>
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/ESelectionService.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/ESelectionService.java
new file mode 100644
index 0000000..8414544
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/ESelectionService.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.ui.selection;
+
+public interface ESelectionService {
+	static final String SELECTION = "selection"; //$NON-NLS-1$
+
+	void setSelection(Object selection);
+
+	Object getSelection();
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/Activator.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/Activator.java
new file mode 100644
index 0000000..cc524d0
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.e4.ui.selection.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.e4.ui.selection"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+	}
+
+	/**
+	 * Returns the shared instance
+	 * 
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionLookupFunction.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionLookupFunction.java
new file mode 100644
index 0000000..966906a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionLookupFunction.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.ui.selection.internal;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+
+/**
+ *
+ */
+public class SelectionLookupFunction extends ContextFunction {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.e4.core.services.context.spi.ContextFunction#compute(org.eclipse.e4.core.services
+	 * .context.IEclipseContext, java.lang.Object[])
+	 */
+	@Override
+	public Object compute(IEclipseContext context, Object[] arguments) {
+		IEclipseContext leafContext = context;
+		IEclipseContext child = (IEclipseContext) leafContext.getLocal(IContextConstants.ACTIVE_CHILD);
+		while (child != null) {
+			leafContext = child;
+			child = (IEclipseContext) leafContext.getLocal(IContextConstants.ACTIVE_CHILD);
+		}
+		return leafContext.get(SelectionServiceImpl.OUT_SELECTION);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceCreationFunction.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceCreationFunction.java
new file mode 100644
index 0000000..e034b5c
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceCreationFunction.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.ui.selection.internal;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.core.services.context.spi.ContextInjectionFactory;
+
+/**
+ *
+ */
+public class SelectionServiceCreationFunction extends ContextFunction {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.e4.core.services.context.spi.ContextFunction#compute(org.eclipse.e4.core.services
+	 * .context.IEclipseContext, java.lang.Object[])
+	 */
+	@Override
+	public Object compute(IEclipseContext context, Object[] arguments) {
+		SelectionServiceImpl impl = new SelectionServiceImpl();
+		ContextInjectionFactory.inject(impl, context);
+		return impl;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceImpl.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceImpl.java
new file mode 100644
index 0000000..f2b0140
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceImpl.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.ui.selection.internal;
+
+import javax.inject.Inject;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.selection.ESelectionService;
+
+/**
+ *
+ */
+public class SelectionServiceImpl implements ESelectionService {
+
+	static final String OUT_SELECTION = "output.selection"; //$NON-NLS-1$
+
+	private IEclipseContext context;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.e4.ui.selection.ESelectionService#setSelection(java.lang.Object)
+	 */
+	public void setSelection(Object selection) {
+		if (selection != null) {
+			context.set(OUT_SELECTION, selection);
+		} else {
+			context.remove(OUT_SELECTION);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.e4.ui.selection.ESelectionService#getSelection()
+	 */
+	public Object getSelection() {
+		return context.get(ESelectionService.SELECTION);
+	}
+
+	@Inject
+	public void setContext(IEclipseContext c) {
+		context = c;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.web/.classpath b/bundles/org.eclipse.e4.ui.web/.classpath
new file mode 100644
index 0000000..2fbb7a2
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.web/.project b/bundles/org.eclipse.e4.ui.web/.project
new file mode 100644
index 0000000..2de00f1
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.web</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e820172
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Wed Jul 08 16:27:06 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..48898c4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,55 @@
+#Sat Oct 24 21:59:03 CEST 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.web/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.web/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..b92bc35
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse UI web embedding (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.web
+Bundle-Version: 0.9.0.qualifier
+Require-Bundle: org.eclipse.swt;bundle-version="3.5.0",
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.equinox.registry;bundle-version="3.4.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Export-Package: org.eclipse.e4.ui.internal.web;x-internal:=true,
+ org.eclipse.e4.ui.web
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.web/build.properties b/bundles/org.eclipse.e4.ui.web/build.properties
new file mode 100644
index 0000000..3884924
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               js/
diff --git a/bundles/org.eclipse.e4.ui.web/js/e4.js b/bundles/org.eclipse.e4.ui.web/js/e4.js
new file mode 100644
index 0000000..a384b89
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/js/e4.js
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hatem, IBM Corporation - initial API and implementation
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+window.e4 = {
+	
+	isInstalled : function() {
+		try {
+			return typeof e4RPC == "function";
+		} catch(e) {
+			return false;
+		}
+	},
+	
+	hasFeature : function(feature) {
+		return this.isInstalled() && typeof this[feature] == "object";
+	},
+	
+	dialogs : {
+		confirm : function(msg) {
+			return e4RPC("dialogs", "confirm", msg);
+		},
+		openFiles : function() {
+			
+		}
+	},
+	
+	clipboard: {
+		getContents : function() {
+			return e4RPC("clipboard", "getContents");
+		}
+	}, 
+	
+	log: {
+		info : function(msg) {
+			return e4RPC("log", "info", msg);
+		}
+	}, 
+	
+	menus : {
+		addContextMenuItem : function(label, callback) {
+			return e4RPC("menus", "addContextMenuItem", label, callback);
+		}
+	},
+	
+	status : {
+		setMessage : function(msg) {
+			return e4RPC("status", "setMessage", msg);
+		},
+		_dirty : false,
+		setDirty : function(dirty) {
+			if (window.e4.status._dirty != dirty) {
+				window.e4.status._dirty = dirty;
+				return e4RPC("status", "setDirty", dirty);
+			}
+		}
+	},
+	
+	saveable : {
+		promptToSaveOnClose : function(callback) {
+			return e4RPC("saveable", "promptToSaveOnClose", callback);
+		},
+		doSave : function(callback) {
+			return e4RPC("saveable", "doSave", callback);
+		}
+	}
+};
diff --git a/bundles/org.eclipse.e4.ui.web/pom.xml b/bundles/org.eclipse.e4.ui.web/pom.xml
new file mode 100644
index 0000000..15a6241
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.eclipse.e4.ui</groupId>
+	<artifactId>org.eclipse.e4.ui.web</artifactId>
+	<version>0.9.0-SNAPSHOT</version>
+	<packaging>eclipse-plugin</packaging>
+
+	<properties>
+		<tycho-version>0.11.1</tycho-version>
+	</properties>
+
+	<repositories>
+		<repository>
+			<id>helios</id>
+			<layout>p2</layout>
+			<url>http://download.eclipse.org/releases/helios</url>
+		</repository>
+	</repositories>
+
+	<build>
+		<plugins>
+			<plugin>
+				<!-- TODO switch to org.eclipse.tycho when it will be publicly available -->
+				<groupId>org.sonatype.tycho</groupId>
+				<artifactId>tycho-maven-plugin</artifactId>
+				<version>${tycho-version}</version>
+				<extensions>true</extensions>
+			</plugin>
+
+		</plugins>
+	</build>
+</project>
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/Base64.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/Base64.java
new file mode 100644
index 0000000..087a13e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/Base64.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.web;
+
+/**
+ * Base64 is a helper class for converting byte arrays to and 
+ * from base 64 encoded Strings.
+ *
+ */
+public class Base64 {
+
+	private static final byte equalSign = (byte) '=';
+
+	static char digits[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
+			'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
+			'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
+			'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
+
+	/**
+	 * This method decodes the byte array in base 64 encoding into a char array
+	 * Base 64 encoding has to be according to the specification given by the
+	 * RFC 1521 (5.2).
+	 * 
+	 * @param data the encoded byte array
+	 * @return the decoded byte array
+	 */
+	public static byte[] decode(byte[] data) {
+		if (data.length == 0) {
+			return data;
+		}
+		int lastRealDataIndex = data.length - 1;
+		while (data[lastRealDataIndex] == equalSign) {
+			lastRealDataIndex--;
+		}
+		// original data digit is 8 bits long, but base64 digit is 6 bits long
+		int padBytes = data.length - 1 - lastRealDataIndex;
+		int byteLength = data.length * 6 / 8 - padBytes;
+		byte[] result = new byte[byteLength];
+		// Each 4 bytes of input (encoded) we end up with 3 bytes of output
+		int dataIndex = 0;
+		int resultIndex = 0;
+		int allBits = 0;
+		// how many result chunks we can process before getting to pad bytes
+		int resultChunks = (lastRealDataIndex + 1) / 4;
+		for (int i = 0; i < resultChunks; i++) {
+			allBits = 0;
+			// Loop 4 times gathering input bits (4 * 6 = 24)
+			for (int j = 0; j < 4; j++) {
+				allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
+			}
+			// Loop 3 times generating output bits (3 * 8 = 24)
+			for (int j = resultIndex + 2; j >= resultIndex; j--) {
+				result[j] = (byte) (allBits & 0xff); // Bottom 8 bits
+				allBits = allBits >>> 8;
+			}
+			resultIndex += 3; // processed 3 result bytes
+		}
+		// Now we do the extra bytes in case the original (non-encoded) data
+		// was not multiple of 3 bytes
+		switch (padBytes) {
+			case 1 :
+				// 1 pad byte means 3 (4-1) extra Base64 bytes of input, 18
+				// bits, of which only 16 are meaningful
+				// Or: 2 bytes of result data
+				allBits = 0;
+				// Loop 3 times gathering input bits
+				for (int j = 0; j < 3; j++) {
+					allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
+				}
+				// NOTE - The code below ends up being equivalent to allBits =
+				// allBits>>>2
+				// But we code it in a non-optimized way for clarity
+				// The 4th, missing 6 bits are all 0
+				allBits = allBits << 6;
+				// The 3rd, missing 8 bits are all 0
+				allBits = allBits >>> 8;
+				// Loop 2 times generating output bits
+				for (int j = resultIndex + 1; j >= resultIndex; j--) {
+					result[j] = (byte) (allBits & 0xff); // Bottom 8
+					// bits
+					allBits = allBits >>> 8;
+				}
+				break;
+			case 2 :
+				// 2 pad bytes mean 2 (4-2) extra Base64 bytes of input, 12 bits
+				// of data, of which only 8 are meaningful
+				// Or: 1 byte of result data
+				allBits = 0;
+				// Loop 2 times gathering input bits
+				for (int j = 0; j < 2; j++) {
+					allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
+				}
+				// NOTE - The code below ends up being equivalent to allBits =
+				// allBits>>>4
+				// But we code it in a non-optimized way for clarity
+				// The 3rd and 4th, missing 6 bits are all 0
+				allBits = allBits << 6;
+				allBits = allBits << 6;
+				// The 3rd and 4th, missing 8 bits are all 0
+				allBits = allBits >>> 8;
+				allBits = allBits >>> 8;
+				result[resultIndex] = (byte) (allBits & 0xff); // Bottom
+				// 8
+				// bits
+				break;
+		}
+		return result;
+	}
+
+	/**
+	 * This method converts a Base 64 digit to its numeric value.
+	 * 
+	 * @param data digit (character) to convert
+	 * @return value for the digit
+	 */
+	static int decodeDigit(byte data) {
+		char charData = (char) data;
+		if (charData <= 'Z' && charData >= 'A') {
+			return charData - 'A';
+		}
+		if (charData <= 'z' && charData >= 'a') {
+			return charData - 'a' + 26;
+		}
+		if (charData <= '9' && charData >= '0') {
+			return charData - '0' + 52;
+		}
+		switch (charData) {
+			case '+' :
+				return 62;
+			case '/' :
+				return 63;
+			default :
+				throw new IllegalArgumentException("Invalid char to decode: " + data); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * This method encodes the byte array into a char array in base 64 according
+	 * to the specification given by the RFC 1521 (5.2).
+	 * 
+	 * @param data the encoded char array
+	 * @return the byte array that needs to be encoded
+	 */
+	public static byte[] encode(byte[] data) {
+		int sourceChunks = data.length / 3;
+		int len = ((data.length + 2) / 3) * 4;
+		byte[] result = new byte[len];
+		int extraBytes = data.length - (sourceChunks * 3);
+		// Each 4 bytes of input (encoded) we end up with 3 bytes of output
+		int dataIndex = 0;
+		int resultIndex = 0;
+		int allBits = 0;
+		for (int i = 0; i < sourceChunks; i++) {
+			allBits = 0;
+			// Loop 3 times gathering input bits (3 * 8 = 24)
+			for (int j = 0; j < 3; j++) {
+				allBits = (allBits << 8) | (data[dataIndex++] & 0xff);
+			}
+			// Loop 4 times generating output bits (4 * 6 = 24)
+			for (int j = resultIndex + 3; j >= resultIndex; j--) {
+				result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
+				// 6
+				// bits
+				allBits = allBits >>> 6;
+			}
+			resultIndex += 4; // processed 4 result bytes
+		}
+		// Now we do the extra bytes in case the original (non-encoded) data
+		// is not multiple of 4 bytes
+		switch (extraBytes) {
+			case 1 :
+				allBits = data[dataIndex++]; // actual byte
+				allBits = allBits << 8; // 8 bits of zeroes
+				allBits = allBits << 8; // 8 bits of zeroes
+				// Loop 4 times generating output bits (4 * 6 = 24)
+				for (int j = resultIndex + 3; j >= resultIndex; j--) {
+					result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
+					// 6
+					// bits
+					allBits = allBits >>> 6;
+				}
+				// 2 pad tags
+				result[result.length - 1] = (byte) '=';
+				result[result.length - 2] = (byte) '=';
+				break;
+			case 2 :
+				allBits = data[dataIndex++]; // actual byte
+				allBits = (allBits << 8) | (data[dataIndex++] & 0xff); // actual
+				// byte
+				allBits = allBits << 8; // 8 bits of zeroes
+				// Loop 4 times generating output bits (4 * 6 = 24)
+				for (int j = resultIndex + 3; j >= resultIndex; j--) {
+					result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
+					// 6
+					// bits
+					allBits = allBits >>> 6;
+				}
+				// 1 pad tag
+				result[result.length - 1] = (byte) '=';
+				break;
+		}
+		return result;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/E4BrowserUtil.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/E4BrowserUtil.java
new file mode 100644
index 0000000..93fc098
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/E4BrowserUtil.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hatem, IBM Corporation - initial API and implementation
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.web;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class E4BrowserUtil {
+	
+	public static byte[] getBytesFromFile(File file) throws IOException {
+        InputStream is = new FileInputStream(file);
+        long length = file.length();  
+        byte[] bytes = new byte[(int)length];
+        int offset = 0;
+        int numRead = 0;
+        while (offset < bytes.length
+               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
+            offset += numRead;
+        }
+        if (offset < bytes.length) {
+            throw new IOException("File read incomplete"+file.getName());
+        }
+        is.close();
+        return bytes;
+    }
+
+	public static byte[] getBytesFromStream(InputStream is) throws IOException {
+		int BUFFER_SIZE = 8192;
+		byte[] buffer = new byte[BUFFER_SIZE];
+		ByteArrayOutputStream os = new ByteArrayOutputStream();
+		int numRead = 0;
+		while ((numRead = is.read(buffer)) > 0) {
+			os.write(buffer, 0, numRead);
+		}
+		return os.toByteArray();
+	}
+	
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserEditorPart.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserEditorPart.java
new file mode 100644
index 0000000..c2ee615
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserEditorPart.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hatem, IBM Corporation - initial API and implementation
+ *     Boris Bokowski, IBM Corporation - initial API and implementation
+ *     Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.ui.internal.web.Base64;
+import org.eclipse.e4.ui.internal.web.E4BrowserUtil;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.CloseWindowListener;
+import org.eclipse.swt.browser.OpenWindowListener;
+import org.eclipse.swt.browser.WindowEvent;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.ISaveablePart2;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
+
+public abstract class BrowserEditorPart extends EditorPart {
+
+	private Browser browser;
+	private BrowserRPC browserRPC;
+	private boolean isDirty;
+	private List menuItems = new ArrayList(3);
+	private SaveableProxy saveable;
+
+	public void createPartControl(Composite parent) {
+		parent.setLayout(new FillLayout());
+		browser = new Browser(parent, SWT.NONE);
+		browser.addOpenWindowListener(new OpenWindowListener() {
+			public void open(WindowEvent event) {
+				BrowserEditorPart view = openWindow(event);
+				if (view != null) {
+					event.browser = view.getBrowser();
+					event.required = true;
+				}
+			}
+		});
+
+		browser.addCloseWindowListener(new CloseWindowListener() {
+			public void close(WindowEvent event) {
+				isDirty = false;
+				getEditorSite().getPage().closeEditor(BrowserEditorPart.this,
+						true);
+			}
+		});
+
+		browserRPC = new BrowserRPC(browser);
+		saveable = new SaveableProxy(browser);
+		browserRPC.addRPCHandler("dialogs", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("confirm".equals(args[1])) {
+					IEditorSite site = getEditorSite();
+					String title = "Confirmation - "
+							+ BrowserEditorPart.this.getTitle();
+					return Boolean.valueOf(MessageDialog.openConfirm(site
+							.getShell(), title, (String) args[2]));
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("clipboard", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("getContents".equals(args[1])) {
+					Clipboard cb = new Clipboard(browser.getDisplay());
+					FileTransfer ft = FileTransfer.getInstance();
+					String[] files = (String[]) cb.getContents(ft);
+					if (files.length > 0) {
+						File file = new File(files[0]);
+						if (file.exists()) {
+							byte[] data;
+							try {
+								data = E4BrowserUtil.getBytesFromFile(file);
+								byte[] encoded = Base64.encode(data);
+								return new String(encoded);
+							} catch (IOException e) {
+								e.printStackTrace();
+							}
+						}
+					}
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("menus", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("addContextMenuItem".equals(args[1])) {
+					menuItems.add(new MenuItemProxy((String) args[2],
+							(String) args[3]));
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("status", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("setMessage".equals(args[1])) {
+					IStatusLineManager slm = getEditorSite().getActionBars()
+							.getStatusLineManager();
+					slm.setMessage((String) args[2]);
+				} else if ("setDirty".equals(args[1])) {
+					isDirty = ((Boolean) args[2]).booleanValue();
+					firePropertyChange(PROP_DIRTY);
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("saveable", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("promptToSaveOnClose".equals(args[1])) {
+					saveable.setPromptCallback((String) args[2]);
+				} else if ("doSave".equals(args[1])) {
+					saveable.setDoSaveCallback((String) args[2]);
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+		configureBrowser(browser);
+
+		// context menu
+		hookContextMenu();
+	}
+
+	protected void configureBrowser(Browser b) {
+	}
+
+	protected BrowserEditorPart openWindow(WindowEvent event) {
+		BrowserEditorPart view = null;
+		try {
+			view = (BrowserEditorPart) getEditorSite().getPage()
+					.openEditor(getNewWindowEditorInput(event),
+							getNewWindowEditorId(event));
+		} catch (PartInitException e) {
+			e.printStackTrace();
+		}
+		return view;
+	}
+
+	protected String getNewWindowEditorId(WindowEvent event) {
+		return getSite().getId();
+	}
+
+	protected abstract IEditorInput getNewWindowEditorInput(WindowEvent event);
+
+	public void setUrl(String url) {
+		browser.setUrl(url);
+	}
+
+	public Browser getBrowser() {
+		return browser;
+	}
+
+	public void setFocus() {
+		browser.setFocus();
+	}
+
+	private void hookContextMenu() {
+		MenuManager menuMgr = new MenuManager("#PopupMenu");
+		menuMgr.setRemoveAllWhenShown(true);
+		menuMgr.addMenuListener(new IMenuListener() {
+			public void menuAboutToShow(IMenuManager manager) {
+				// fill context menu
+				Iterator itr = menuItems.iterator();
+				while (itr.hasNext()) {
+					final MenuItemProxy mi = (MenuItemProxy) itr.next();
+					Action action = new Action(mi.getLabel()) {
+						public void run() {
+							browser.execute(mi.getCallback());
+						}
+					};
+					manager.add(action);
+				}
+			}
+		});
+		Menu menu = menuMgr.createContextMenu(browser);
+		browser.setMenu(menu);
+
+		// TODO implement a selection provider wrapper for browser
+		// getSite().registerContextMenu(menuMgr, browser);
+	}
+
+	public int promptToSaveOnClose() {
+		return saveable.promptToSaveOnClose();
+	}
+
+	public void doSave(IProgressMonitor monitor) {
+		saveable.doSave(monitor);
+	}
+
+	public void doSaveAs() {
+	}
+
+	public boolean isDirty() {
+		return isDirty;
+	}
+
+	public boolean isSaveAsAllowed() {
+		return false;
+	}
+
+	public boolean isSaveOnCloseNeeded() {
+		return isDirty();
+	}
+
+	private class MenuItemProxy {
+		private String label;
+		private String callback;
+
+		public MenuItemProxy(String label, String callback) {
+			this.label = label;
+			this.callback = callback;
+		}
+
+		public String getLabel() {
+			return label;
+		}
+
+		public String getCallback() {
+			return callback;
+		}
+	}
+
+	private class SaveableProxy {
+		private String promptCallback;
+		private String dosaveCallback;
+		private Browser browser;
+
+		public SaveableProxy(Browser browser) {
+			this.browser = browser;
+		}
+
+		public void setPromptCallback(String promptCallback) {
+			this.promptCallback = promptCallback;
+		}
+
+		public void setDoSaveCallback(String dosaveCallback) {
+			this.dosaveCallback = dosaveCallback;
+		}
+
+		public int promptToSaveOnClose() {
+			if (promptCallback != null) {
+				Double i = (Double) browser.evaluate(promptCallback);
+				if (i != null) {
+					return i.intValue();
+				}
+			}
+			return ISaveablePart2.DEFAULT;
+		}
+
+		public void doSave(IProgressMonitor monitor) {
+			if (dosaveCallback != null) {
+				browser.execute(dosaveCallback);
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPC.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPC.java
new file mode 100644
index 0000000..040b1b9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPC.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hatem, IBM Corporation - initial API and implementation
+ *     Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.e4.ui.internal.web.E4BrowserUtil;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.browser.LocationListener;
+import org.eclipse.swt.browser.ProgressEvent;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+public class BrowserRPC {
+
+	private static final String UNDEFINED = "undefined";
+
+	private BrowserFunction rpcFunction;
+
+	private Map/* String, BrowserRPCHandler */handlers = new HashMap();
+
+	private Browser browser;
+
+	public BrowserRPC(Browser browser) {
+		this.browser = browser;
+		final String e4Script;
+		try {
+			e4Script = new String(E4BrowserUtil.getBytesFromStream(getClass()
+					.getClassLoader().getResourceAsStream("js/e4.js")),
+					"ISO-8859-1");
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		// we need to register the ipc each time
+		// the location for the browser changes
+		browser.addLocationListener(new LocationListener() {
+			public void changed(LocationEvent event) {
+				registerRPC();
+			}
+
+			public void changing(LocationEvent event) {
+			}
+		});
+		registerRPC();
+		browser.addProgressListener(new ProgressListener() {
+			public void completed(ProgressEvent event) {
+				if (!BrowserRPC.this.browser.execute(e4Script)) {
+					MessageDialog.openError(BrowserRPC.this.browser.getShell(),
+							"Error", "Error executing e4 script");
+				}
+			}
+
+			public void changed(ProgressEvent event) {
+			}
+		});
+		browser.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				removeAllRPCHandlers();
+			}
+		});
+	}
+
+	private void registerRPC() {
+		if (rpcFunction != null) {
+			rpcFunction.dispose();
+		}
+		rpcFunction = new BrowserFunction(browser, "e4RPC") {
+			public Object function(Object[] arguments) {
+				BrowserRPCHandler handler = (BrowserRPCHandler) handlers
+						.get(arguments[0]);
+				if (handler != null) {
+					return handler.handle(browser, arguments);
+				}
+				return UNDEFINED;
+			}
+		};
+	}
+
+	public void addRPCHandler(String function, BrowserRPCHandler handler) {
+		if (handlers.get(function) != null) {
+			throw new IllegalArgumentException();
+		}
+		handlers.put(function, handler);
+	}
+
+	public void removeRPCHandler(String function) {
+		BrowserRPCHandler oldHandler = (BrowserRPCHandler) handlers
+				.remove(function);
+		if (oldHandler != null) {
+			oldHandler.dispose();
+		}
+	}
+
+	private void removeAllRPCHandlers() {
+		String[] handlerFunction = (String[]) handlers.keySet().toArray(
+				new String[0]);
+		for (int i = 0; i < handlerFunction.length; i++) {
+			removeRPCHandler(handlerFunction[i]);
+		}
+
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPCHandler.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPCHandler.java
new file mode 100644
index 0000000..c065362
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPCHandler.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hatem, IBM Corporation - initial API and implementation
+ *     Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import org.eclipse.swt.browser.Browser;
+
+public interface BrowserRPCHandler {
+
+	public Object handle(final Browser browser, final Object[] arguments);
+
+	public void dispose();
+
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserViewPart.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserViewPart.java
new file mode 100644
index 0000000..bb1fbae
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserViewPart.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hatem, IBM Corporation - initial API and implementation
+ *     Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.e4.ui.internal.web.Base64;
+import org.eclipse.e4.ui.internal.web.E4BrowserUtil;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.*;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.*;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+public abstract class BrowserViewPart extends ViewPart implements ISaveablePart2 {
+
+	protected Browser browser;
+	private BrowserRPC browserRPC;
+	private boolean isDirty;
+	private List menuItems = new ArrayList(3);
+	private SaveableProxy saveable;
+
+	public void createPartControl(Composite parent) {
+		parent.setLayout(new FillLayout());
+		browser = new Browser(parent, SWT.NONE);
+		browserRPC = new BrowserRPC(browser);
+		saveable = new SaveableProxy(browser);
+		browser.addOpenWindowListener(new OpenWindowListener() {
+			public void open(WindowEvent event) {
+				BrowserViewPart view = openWindow(event);
+				if (view != null) {
+					event.browser = view.getBrowser();
+					event.required = true;
+				}
+			}
+		});
+
+		browser.addCloseWindowListener(new CloseWindowListener() {
+			public void close(WindowEvent event) {
+				isDirty = false;
+				getViewSite().getPage().hideView(BrowserViewPart.this);
+			}
+		});
+
+		browserRPC.addRPCHandler("dialogs", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("confirm".equals(args[1])) {
+					IViewSite site = getViewSite();
+					String title = "Confirmation - " + BrowserViewPart.this.getTitle();
+					return Boolean.valueOf(MessageDialog.openConfirm(site.getShell(), title, (String) args[2]));
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("clipboard", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("getContents".equals(args[1])) {
+					Clipboard cb = new Clipboard(browser.getDisplay());
+					FileTransfer ft = FileTransfer.getInstance();
+					String[] files = (String[]) cb.getContents(ft);
+					if (files.length > 0) {
+						File file = new File(files[0]);
+						if (file.exists()) {
+							byte[] data;
+							try {
+								data = E4BrowserUtil.getBytesFromFile(file);
+								byte[] encoded = Base64.encode(data);
+								return new String(encoded);
+							} catch (IOException e) {
+								e.printStackTrace();
+							}
+						}
+					}
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("log", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				int statusSeverity = IStatus.INFO;
+				if ("info".equals(args[1]))
+					statusSeverity = IStatus.INFO;
+				else if ("warning".equals(args[1]))
+					statusSeverity = IStatus.WARNING;
+				else if ("error".equals(args[1]))
+					statusSeverity = IStatus.ERROR;
+
+				if ("info".equals(args[1])) {
+					StatusManager.getManager().handle(new Status(statusSeverity, "opensocial-demo", (String) args[2]));
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("menus", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("addContextMenuItem".equals(args[1])) {
+					menuItems.add(new MenuItemProxy((String) args[2], (String) args[3]));
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("status", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("setMessage".equals(args[1])) {
+					IStatusLineManager slm = getViewSite().getActionBars().getStatusLineManager();
+					slm.setMessage((String) args[2]);
+				} else if ("setDirty".equals(args[1])) {
+					isDirty = ((Boolean) args[2]).booleanValue();
+					firePropertyChange(PROP_DIRTY);
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		browserRPC.addRPCHandler("saveable", new BrowserRPCHandler() {
+			public Object handle(Browser browser, Object[] args) {
+				if ("promptToSaveOnClose".equals(args[1])) {
+					saveable.setPromptCallback((String) args[2]);
+				} else if ("doSave".equals(args[1])) {
+					saveable.setDoSaveCallback((String) args[2]);
+				}
+				return null;
+			}
+
+			public void dispose() {
+				// Nothing
+			}
+		});
+
+		configureBrowser(browser);
+		// context menu
+		// hookContextMenu();
+	}
+
+	abstract protected void configureBrowser(Browser browser);
+
+	protected abstract String getNewWindowViewId();
+
+	protected BrowserViewPart openWindow(WindowEvent event) {
+		BrowserViewPart view = null;
+		try {
+			view = (BrowserViewPart) getViewSite().getPage().showView(getNewWindowViewId(), String.valueOf(System.currentTimeMillis()), IWorkbenchPage.VIEW_ACTIVATE);
+		} catch (PartInitException e) {
+			e.printStackTrace();
+		}
+		return view;
+	}
+
+	public void setUrl(String url) {
+		browser.setUrl(url);
+	}
+
+	public Browser getBrowser() {
+		return browser;
+	}
+
+	public void setFocus() {
+		browser.setFocus();
+	}
+
+	void hookContextMenu() {
+		MenuManager menuMgr = new MenuManager("#PopupMenu");
+		menuMgr.setRemoveAllWhenShown(true);
+		menuMgr.addMenuListener(new IMenuListener() {
+			public void menuAboutToShow(IMenuManager manager) {
+				// fill context menu
+				Iterator itr = menuItems.iterator();
+				while (itr.hasNext()) {
+					final MenuItemProxy mi = (MenuItemProxy) itr.next();
+					Action action = new Action(mi.getLabel()) {
+						public void run() {
+							browser.execute(mi.getCallback());
+						}
+					};
+					manager.add(action);
+				}
+			}
+		});
+		Menu menu = menuMgr.createContextMenu(browser);
+		browser.setMenu(menu);
+
+		// TODO implement a selection provider wrapper for browser
+		// getSite().registerContextMenu(menuMgr, browser);
+	}
+
+	public int promptToSaveOnClose() {
+		return saveable.promptToSaveOnClose();
+	}
+
+	public void doSave(IProgressMonitor monitor) {
+		saveable.doSave(monitor);
+	}
+
+	public void doSaveAs() {
+	}
+
+	public boolean isDirty() {
+		return isDirty;
+	}
+
+	public boolean isSaveAsAllowed() {
+		return false;
+	}
+
+	public boolean isSaveOnCloseNeeded() {
+		return isDirty();
+	}
+
+	private class MenuItemProxy {
+		private String label;
+		private String callback;
+
+		public MenuItemProxy(String label, String callback) {
+			this.label = label;
+			this.callback = callback;
+		}
+
+		public String getLabel() {
+			return label;
+		}
+
+		public String getCallback() {
+			return callback;
+		}
+	}
+
+	private class SaveableProxy {
+		private String promptCallback;
+		private String dosaveCallback;
+		private Browser browser;
+
+		public SaveableProxy(Browser browser) {
+			this.browser = browser;
+		}
+
+		public void setPromptCallback(String promptCallback) {
+			this.promptCallback = promptCallback;
+		}
+
+		public void setDoSaveCallback(String dosaveCallback) {
+			this.dosaveCallback = dosaveCallback;
+		}
+
+		public int promptToSaveOnClose() {
+			if (promptCallback != null) {
+				Double i = (Double) browser.evaluate(promptCallback);
+				if (i != null) {
+					return i.intValue();
+				}
+			}
+			return ISaveablePart2.DEFAULT;
+		}
+
+		public void doSave(IProgressMonitor monitor) {
+			if (dosaveCallback != null) {
+				browser.execute(dosaveCallback);
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.classpath b/bundles/org.eclipse.e4.ui.workbench.fragment/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.cvsignore b/bundles/org.eclipse.e4.ui.workbench.fragment/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.project b/bundles/org.eclipse.e4.ui.workbench.fragment/.project
new file mode 100644
index 0000000..52bfeae
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.workbench.fragment</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3e499cf
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,354 @@
+#Fri Apr 03 07:41:10 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 0000000..93cdd49
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+#Wed Dec 03 10:31:31 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..0308585
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+#Fri Jun 12 14:32:58 EDT 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
+formatter_settings_version=11
+internal.default.compliance=user
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return Returns the ${bare_field_name}.\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} The ${bare_field_name} to set.\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************\n * Copyright (c) ${year} IBM Corporation and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n *     IBM Corporation - initial API and implementation\n ******************************************************************************/\n</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @since 3.3\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..7f9ef27
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,14 @@
+#Tue Nov 23 11:21:27 EST 2004
+compilers.p.unused-element-or-attribute=1
+compilers.p.unresolved-ex-points=0
+compilers.p.deprecated=0
+compilers.p.unknown-element=1
+compilers.p.unknown-resource=1
+compilers.p.unknown-class=1
+compilers.p.unknown-attribute=0
+compilers.p.no-required-att=0
+eclipse.preferences.version=1
+compilers.p.unresolved-import=0
+compilers.p.not-externalized-att=0
+compilers.p.illegal-att-value=0
+compilers.use-project=true
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/Application.xmi b/bundles/org.eclipse.e4.ui.workbench.fragment/Application.xmi
new file mode 100644
index 0000000..f202148
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/Application.xmi
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ASCII"?>
+<org.eclipse.e4.ui.model.application:MApplication xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:org.eclipse.e4.ui.model.application="http://www.eclipse.org/ui/2008/Application" xsi:schemaLocation="http://www.eclipse.org/ui/2008/Application ../org.eclipse.e4.ui.model.workbench/model/Application.ecore">
+  <windows x="100" y="100" width="800" height="600">
+    <menu>
+      <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="File">
+        <menu>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" id="" name="Do Nothing"/>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="---" separator="true"/>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+        </menu>
+      </items>
+      <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Edit">
+        <menu>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+        </menu>
+      </items>
+      <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Help">
+        <menu>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+        </menu>
+      </items>
+    </menu>
+    <children policy="VerticalComposite">
+      <toolBar>
+        <items xsi:type="org.eclipse.e4.ui.model.application:MToolBarItem" name="You Are Seeing The Default Application.xmi"/>
+      </toolBar>
+      <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="HorizontalSash">
+        <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+          <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+            <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Library" tooltip="" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+          </children>
+        </children>
+        <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+          <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Preview" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+          <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+            <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Thumbnails" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+            <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Exif" tooltip="" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+          </children>
+          <weights>70</weights>
+          <weights>30</weights>
+        </children>
+        <weights>30</weights>
+        <weights>70</weights>
+      </children>
+    </children>
+    <handlers URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.ExitHandler" command="//@command.0"/>
+  </windows>
+  <command id="org.eclipse.e4.ui.workbench.exit" name="Exit"/>
+</org.eclipse.e4.ui.model.application:MApplication>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.workbench.fragment/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a7e5dc3
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %fragmentName
+Bundle-SymbolicName: org.eclipse.e4.ui.workbench.fragment;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Bundle-Vendor: %providerName
+Fragment-Host: org.eclipse.ui.workbench;bundle-version="[3.0.0,4.0.0)"
+Bundle-Localization: fragment-compatibility
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ClassPath: e4-workbench.jar
+Require-Bundle: org.eclipse.e4.ui.workbench;bundle-version="0.9.0",
+ org.eclipse.core.runtime;bundle-version="3.4.100",
+ org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench.renderers.swt,
+ org.eclipse.e4.ui.workbench.swt,
+ org.eclipse.e4.ui.services;bundle-version="0.9.0",
+ org.eclipse.e4.ui.widgets;bundle-version="0.9.0",
+ org.eclipse.e4.ui.model.workbench;bundle-version="0.9.0",
+ org.eclipse.e4.core.commands;bundle-version="0.9.0"
+Export-Package: org.eclipse.e4.compatibility,
+ org.eclipse.e4.extensions,
+ org.eclipse.e4.workbench.ui.api,
+ org.eclipse.e4.workbench.ui.menus,
+ org.eclipse.ui,
+ org.eclipse.ui.internal;x-internal:=true,
+ org.eclipse.ui.part
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/about.html b/bundles/org.eclipse.e4.ui.workbench.fragment/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/build.properties b/bundles/org.eclipse.e4.ui.workbench.fragment/build.properties
new file mode 100644
index 0000000..a8878ad
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/build.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# Copyright (c) 2003, 2008 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+source.e4-workbench.jar=src/
+src.includes=about.html
+bin.includes = fragment-compatibility.properties,\
+               about.html,\
+               e4-workbench.jar,\
+               META-INF/,\
+               fragment.xml
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/fragment-compatibility.properties b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment-compatibility.properties
new file mode 100644
index 0000000..f5c8844
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment-compatibility.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2003, 2005 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+providerName=Eclipse.org
+fragmentName=Workbench Compatibility (Incubation)
+
+perspective.name.f0 = Compatibility Test Perspective
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/fragment.xml b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment.xml
new file mode 100644
index 0000000..9441a04
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<fragment>
+
+</fragment>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/Activator.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/Activator.java
new file mode 100644
index 0000000..fe84207
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.e4.compatibility;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.e4.compatibility"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyEditor.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyEditor.java
new file mode 100644
index 0000000..e92b87f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyEditor.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.compatibility;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.extensions.ModelEditorReference;
+import org.eclipse.e4.ui.internal.workbench.Trackable;
+import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.widgets.CTabFolder;
+import org.eclipse.e4.ui.widgets.CTabItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.internal.EditorActionBars;
+import org.eclipse.ui.internal.EditorActionBuilder;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.ViewSite;
+import org.eclipse.ui.internal.WorkbenchPage;
+import org.eclipse.ui.internal.registry.EditorDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+
+/**
+ * This class is an implementation of an MPart that can be used to host a 3.x
+ * EditorPart into an Eclipse 4.0 application.
+ * 
+ * @since 4.0
+ * 
+ */
+public class LegacyEditor {
+	public final static String LEGACY_VIEW_URI = "bundleclass://org.eclipse.ui.workbench/org.eclipse.e4.compatibility.LegacyEditor"; //$NON-NLS-1$
+
+	private static final String IS_DIRTY = "isDirty"; //$NON-NLS-1$
+	private static final String EDITOR_DISPOSED = "editorDisposed"; //$NON-NLS-1$
+
+	private MPart editorPart;
+	private IEditorPart editorWBPart;
+
+	private Map<IEditorPart, Trackable> trackables = new HashMap<IEditorPart, Trackable>();
+
+	/**
+	 * Create and initialize a 3.x editor from an e4 contribution
+	 * 
+	 * @param parent
+	 *            The SWT parent for the editor
+	 * @param context
+	 *            The context under which this part is being created
+	 * @param part
+	 *            The MPart representing the editor
+	 */
+	public LegacyEditor(final Composite parent, IEclipseContext context,
+			final MPart part) {
+		editorPart = part;
+
+		IConfigurationElement editorElement = findEditorConfig(part.getId());
+
+		EditorDescriptor desc = new EditorDescriptor(part.getId(),
+				editorElement);
+
+		parent.setLayout(new FillLayout());
+
+		// Convert the relative path into a bundle URI
+		String imagePath = editorElement.getAttribute("icon"); //$NON-NLS-1$
+		String imageURI = imagePath;
+		if (!imagePath.startsWith("platform:")) { //$NON-NLS-1$
+			imagePath = imagePath.replace("$nl$", ""); //$NON-NLS-1$//$NON-NLS-2$
+			if (imagePath.charAt(0) != '/') {
+				imagePath = '/' + imagePath;
+			}
+			String bundleId = editorElement.getContributor().getName();
+			imageURI = "platform:/plugin/" + bundleId + imagePath; //$NON-NLS-1$
+		}
+
+		part.setIconURI(imageURI);
+
+		try {
+			editorWBPart = desc.createEditor();
+		} catch (CoreException e) {
+			e.printStackTrace();
+		}
+
+		if (editorWBPart == null)
+			return;
+
+		try {
+			final IEclipseContext localContext = part.getContext();
+			IEclipseContext parentContext = (IEclipseContext) localContext
+					.get(IContextConstants.PARENT);
+
+			localContext.set(IContextConstants.DEBUG_STRING, "Legacy Editor(" //$NON-NLS-1$
+					+ desc.getLabel() + ")"); //$NON-NLS-1$
+			parentContext.set(IContextConstants.ACTIVE_CHILD, localContext);
+
+			part.setObject(editorWBPart);
+			// Assign a 'site' for the newly instantiated part
+			WorkbenchPage page = (WorkbenchPage) localContext
+					.get(WorkbenchPage.class.getName());
+			ModelEditorReference ref = new ModelEditorReference(part, page);
+			EditorSite site = new EditorSite(ref, editorWBPart, page);
+			EditorActionBars bars = getEditorActionBars(desc, page,
+					page.getWorkbenchWindow(), part.getId());
+			site.setActionBars(bars);
+			site.setConfigurationElement(editorElement);
+			editorWBPart.init(site, (IEditorInput) localContext
+					.get(IEditorInput.class.getName()));
+
+			editorWBPart.createPartControl(parent);
+			localContext.set(MPart.class.getName(), part);
+
+			// HACK!! presumes it's the -last- child of the parent
+			if (parent.getChildren().length > 0) {
+				Control newCtrl = parent.getChildren()[parent.getChildren().length - 1];
+				newCtrl.addDisposeListener(new DisposeListener() {
+					public void widgetDisposed(DisposeEvent e) {
+						disposeEditor(editorPart);
+					}
+				});
+			}
+
+			// Manage the 'dirty' state
+			final IEditorPart implementation = editorWBPart;
+			localContext.set(IS_DIRTY, implementation.isDirty());
+			localContext.set(EDITOR_DISPOSED, Boolean.FALSE);
+
+			Trackable updateDirty = new Trackable(localContext) {
+				private CTabItem findItemForPart(CTabFolder ctf) {
+					CTabItem[] items = ctf.getItems();
+					for (int i = 0; i < items.length; i++) {
+						if (items[i].getData(AbstractPartRenderer.OWNING_ME) == part) {
+							return items[i];
+						}
+					}
+
+					return null;
+				}
+
+				public void run() {
+					if (!participating) {
+						return;
+					}
+					trackingContext.get(EDITOR_DISPOSED);
+					boolean dirty = (Boolean) trackingContext.get(IS_DIRTY);
+					if (parent instanceof CTabFolder) {
+						CTabFolder ctf = (CTabFolder) parent;
+						CTabItem partItem = findItemForPart(ctf);
+						if (partItem == null)
+							return;
+
+						String itemText = partItem.getText();
+						if (dirty && itemText.indexOf('*') != 0) {
+							itemText = '*' + itemText;
+						} else if (itemText.indexOf('*') == 0) {
+							itemText = itemText.substring(1);
+						}
+						partItem.setText(itemText);
+					}
+				}
+			};
+			trackables.put(implementation, updateDirty);
+			localContext.runAndTrack(updateDirty);
+			editorWBPart.addPropertyListener(new IPropertyListener() {
+				public void propertyChanged(Object source, int propId) {
+					localContext.set(IS_DIRTY, implementation.isDirty());
+				}
+			});
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	protected void disposeEditor(MPart part) {
+		Object obj = part.getObject();
+		if (!(obj instanceof IWorkbenchPart))
+			return;
+
+		if (obj instanceof IEditorPart) {
+			Activator.trace(Policy.DEBUG_RENDERER,
+					"Disposing tracker for " + obj, null); //$NON-NLS-1$
+			Trackable t = trackables.remove(obj);
+			t.participating = false;
+			part.getContext().set(EDITOR_DISPOSED, Boolean.TRUE);
+		}
+		((IWorkbenchPart) obj).dispose();
+		if (obj instanceof IEditorPart) {
+			EditorSite site = (EditorSite) ((IEditorPart) obj).getEditorSite();
+			disposeEditorActionBars((EditorActionBars) site.getActionBars());
+			site.dispose();
+		} else if (obj instanceof IViewPart) {
+			ViewSite site = (ViewSite) ((IViewPart) obj).getViewSite();
+			SubActionBars bars = (SubActionBars) site.getActionBars();
+			bars.dispose();
+			site.dispose();
+		}
+		part.setObject(null);
+	}
+
+	Map<String, EditorActionBars> actionCache = new HashMap<String, EditorActionBars>();
+
+	private EditorActionBars getEditorActionBars(EditorDescriptor desc,
+			WorkbenchPage page, IWorkbenchWindow workbenchWindow, String type) {
+		// Get the editor type.
+
+		// If an action bar already exists for this editor type return it.
+		EditorActionBars actionBars = actionCache.get(type);
+		if (actionBars != null) {
+			actionBars.addRef();
+			return actionBars;
+		}
+
+		// Create a new action bar set.
+		actionBars = new EditorActionBars(page, workbenchWindow, type);
+		actionBars.addRef();
+		actionCache.put(type, actionBars);
+
+		// Read base contributor.
+		IEditorActionBarContributor contr = desc.createActionBarContributor();
+		if (contr != null) {
+			actionBars.setEditorContributor(contr);
+			contr.init(actionBars, page);
+		}
+
+		// Read action extensions.
+		EditorActionBuilder builder = new EditorActionBuilder();
+		contr = builder.readActionExtensions(desc);
+		if (contr != null) {
+			actionBars.setExtensionContributor(contr);
+			contr.init(actionBars, page);
+		}
+
+		// Return action bars.
+		return actionBars;
+	}
+
+	private void disposeEditorActionBars(EditorActionBars actionBars) {
+		actionBars.removeRef();
+		if (actionBars.getRef() <= 0) {
+			String type = actionBars.getEditorType();
+			actionCache.remove(type);
+			actionBars.dispose();
+		}
+	}
+
+	private IConfigurationElement findEditorConfig(String id) {
+		IConfigurationElement[] editors = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_EDITOR);
+		IConfigurationElement editorContribution = ExtensionUtils
+				.findExtension(editors, id);
+		return editorContribution;
+	}
+
+	/**
+	 * @return The client implementation of their 3.x part
+	 */
+	public IEditorPart getEditorWBPart() {
+		return editorWBPart;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyView.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyView.java
new file mode 100644
index 0000000..cd98b2e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyView.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.compatibility;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.extensions.ModelViewReference;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
+import org.eclipse.e4.workbench.ui.menus.MenuHelper;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.internal.ViewSite;
+import org.eclipse.ui.internal.WorkbenchPage;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.menus.IMenuService;
+
+/**
+ * This class is an implementation of an MPart that can be used to host a 3.x
+ * ViewPart into an Eclipse 4.0 org.eclipse.e4.ui.model.application.
+ * 
+ * @since 4.0
+ * 
+ */
+public class LegacyView {
+	public final static String LEGACY_VIEW_URI = "bundleclass://org.eclipse.ui.workbench/org.eclipse.e4.compatibility.LegacyView"; //$NON-NLS-1$
+	private IViewPart impl;
+
+	public LegacyView(Composite parent, IEclipseContext context, MPart part) {
+		// KLUDGE: the progress view assumes a grid layout, we should fix that
+		// in 3.6
+		Set kludge = new HashSet();
+		kludge.add("org.eclipse.ui.views.ProgressView"); //$NON-NLS-1$
+		kludge.add("org.eclipse.pde.runtime.LogView"); //$NON-NLS-1$
+		if (kludge.contains(part.getId())) {
+			parent.setLayout(new GridLayout());
+		} else {
+			parent.setLayout(new FillLayout());
+		}
+
+		// Button btn = new Button(parent, SWT.BORDER);
+		// btn.setText(part.getName());
+		// if (btn != null)
+		// return;
+		String viewId = part.getId();
+		IConfigurationElement viewContribution = findViewConfig(viewId);
+		try {
+			impl = (IViewPart) viewContribution
+					.createExecutableExtension("class"); //$NON-NLS-1$
+		} catch (CoreException e) {
+			e.printStackTrace();
+		}
+		if (impl == null)
+			return;
+
+		try {
+			final IEclipseContext localContext = part.getContext();
+			localContext.set(IContextConstants.DEBUG_STRING, "Legacy View(" //$NON-NLS-1$
+					+ part.getName() + ")"); //$NON-NLS-1$
+
+			part.setObject(this);
+			// Assign a 'site' for the newly instantiated part
+			WorkbenchPage page = (WorkbenchPage) localContext
+					.get(WorkbenchPage.class.getName());
+			ModelViewReference ref = new ModelViewReference(part, page);
+			ViewSite site = new ViewSite(ref, impl, page);
+			site.setConfigurationElement(viewContribution);
+			impl.init(site, null);
+			// final ToolBarManager tbm = (ToolBarManager) site.getActionBars()
+			// .getToolBarManager();
+			// if (parent instanceof CTabFolder) {
+			// final ToolBar tb = tbm.createControl(parent);
+			// ((CTabFolder) parent).setTopRight(tb);
+			// }
+
+			// We need to create the actual TB (some parts call 'getControl')
+			ToolBarManager tbMgr = (ToolBarManager) site.getActionBars()
+					.getToolBarManager();
+			tbMgr.createControl(parent);
+
+			impl.createPartControl(parent);
+
+			localContext.set(MPart.class.getName(), part);
+
+			// Populate and scrape the old-style contributions...
+			IMenuService menuSvc = (IMenuService) localContext
+					.get(IMenuService.class.getName());
+
+			String tbURI = "toolbar:" + part.getId(); //$NON-NLS-1$
+			menuSvc.populateContributionManager(tbMgr, tbURI);
+			MToolBar viewTB = MApplicationFactory.eINSTANCE.createToolBar();
+			MenuHelper.processToolbarManager(localContext, viewTB,
+					tbMgr.getItems());
+			part.setToolbar(viewTB);
+			tbMgr.getControl().dispose();
+
+			String menuURI = "menu:" + part.getId(); //$NON-NLS-1$
+			MenuManager menuMgr = (MenuManager) site.getActionBars()
+					.getMenuManager();
+			menuSvc.populateContributionManager(menuMgr, menuURI);
+			MMenu viewMenu = MApplicationFactory.eINSTANCE.createMenu();
+			viewMenu.setId(menuURI);
+			MenuHelper.processMenuManager(localContext, viewMenu,
+					menuMgr.getItems());
+			part.getMenus().add(viewMenu);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * @return The implementation of the cient's 3.x view part
+	 */
+	public IViewPart getViewPart() {
+		return impl;
+	}
+
+	private IConfigurationElement findViewConfig(String id) {
+		IConfigurationElement[] views = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_VIEWS);
+		IConfigurationElement viewContribution = ExtensionUtils.findExtension(
+				views, id);
+		return viewContribution;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ExtensionUtils.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ExtensionUtils.java
new file mode 100644
index 0000000..2061a5f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ExtensionUtils.java
@@ -0,0 +1,31 @@
+package org.eclipse.e4.extensions;
+
+import org.eclipse.core.internal.runtime.InternalPlatform;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+
+public class ExtensionUtils {
+	public static IConfigurationElement[] getExtensions(String extensionId) {
+		IExtensionRegistry registry = InternalPlatform.getDefault().getRegistry();
+		String extId = "org.eclipse.ui." + extensionId; //$NON-NLS-1$
+		IConfigurationElement[] exts = registry.getConfigurationElementsFor(extId);
+		return exts;
+	}
+	
+	public static  IConfigurationElement findExtension(IConfigurationElement[] extensions, String attId, String id) {
+		if (id == null || id.length() == 0)
+			return null;
+		
+		for (int i = 0; i < extensions.length; i++) {
+			String extId = extensions[i].getAttribute(attId);
+			if (id.equals(extId))
+				return extensions[i];
+		}
+		
+		return null;
+	}
+	
+	public static  IConfigurationElement findExtension(IConfigurationElement[] extensions, String id) {
+		return findExtension(extensions, "id", id); //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelEditorReference.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelEditorReference.java
new file mode 100644
index 0000000..9e92df9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelEditorReference.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.extensions;
+
+import org.eclipse.e4.ui.model.application.MPart;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ */
+public class ModelEditorReference extends ModelReference implements
+		IEditorReference {
+
+	/**
+	 * @param model
+	 * @param page
+	 */
+	public ModelEditorReference(MPart model, WorkbenchPage page) {
+		super(model, page);
+		// TODO Auto-generated constructor stub
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorReference#getEditor(boolean)
+	 */
+	public IEditorPart getEditor(boolean restore) {
+		return (IEditorPart) getPart(restore);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorReference#getEditorInput()
+	 */
+	public IEditorInput getEditorInput() {
+		// the "compatibility" way
+		Object object = getPart(false);
+		if (object instanceof IEditorPart)
+			return ((IEditorPart) object).getEditorInput();
+		// the E4 way
+		return (IEditorInput) getModel().getContext().get(
+				IEditorInput.class.getName());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorReference#getFactoryId()
+	 */
+	public String getFactoryId() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorReference#getName()
+	 */
+	public String getName() {
+		return getModel().getName();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorReference#isPinned()
+	 */
+	public boolean isPinned() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelReference.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelReference.java
new file mode 100644
index 0000000..83c242d
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelReference.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.extensions;
+
+import org.eclipse.e4.ui.model.application.MPart;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ * 
+ */
+public class ModelReference implements IWorkbenchPartReference {
+
+	private MPart modelPart;
+	private WorkbenchPage page;
+	private Image titleImage;
+
+	public ModelReference(MPart model, WorkbenchPage page) {
+		modelPart = model;
+		this.page = page;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbenchPartReference#addPartPropertyListener(org.eclipse
+	 * .jface.util.IPropertyChangeListener)
+	 */
+	public void addPartPropertyListener(IPropertyChangeListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbenchPartReference#addPropertyListener(org.eclipse
+	 * .ui.IPropertyListener)
+	 */
+	public void addPropertyListener(IPropertyListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getContentDescription()
+	 */
+	public String getContentDescription() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getId()
+	 */
+	public String getId() {
+		return modelPart.getId();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getPage()
+	 */
+	public IWorkbenchPage getPage() {
+		return page;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getPart(boolean)
+	 */
+	public IWorkbenchPart getPart(boolean restore) {
+		Object object = modelPart.getObject();
+		if (object instanceof IWorkbenchPart)
+			return (IWorkbenchPart) object;
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getPartName()
+	 */
+	public String getPartName() {
+		return modelPart.getName();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbenchPartReference#getPartProperty(java.lang.String)
+	 */
+	public String getPartProperty(String key) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getTitle()
+	 */
+	public String getTitle() {
+		return modelPart.getName();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getTitleImage()
+	 */
+	public Image getTitleImage() {
+		if (titleImage != null) {
+			return titleImage;
+		}
+		if (modelPart.getIconURI() != null) {
+			try {
+				titleImage = JFaceResources.getResources().createImage(
+						ImageDescriptor.createFromURL(new URL(modelPart
+								.getIconURI())));
+				return titleImage;
+			} catch (MalformedURLException e) {
+				Activator.trace(Policy.DEBUG_WORKBENCH, "Failed to get image", //$NON-NLS-1$
+						e);
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#getTitleToolTip()
+	 */
+	public String getTitleToolTip() {
+		return modelPart.getName();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartReference#isDirty()
+	 */
+	public boolean isDirty() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbenchPartReference#removePartPropertyListener(org
+	 * .eclipse.jface.util.IPropertyChangeListener)
+	 */
+	public void removePartPropertyListener(IPropertyChangeListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbenchPartReference#removePropertyListener(org.eclipse
+	 * .ui.IPropertyListener)
+	 */
+	public void removePropertyListener(IPropertyListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	public MPart getModel() {
+		return modelPart;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelViewReference.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelViewReference.java
new file mode 100644
index 0000000..ba689db
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelViewReference.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.extensions;
+
+import org.eclipse.e4.ui.model.application.MPart;
+
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ * @since 3.3
+ * 
+ */
+public class ModelViewReference extends ModelReference implements
+		IViewReference {
+
+	/**
+	 * @param model
+	 * @param page
+	 */
+	public ModelViewReference(MPart model, WorkbenchPage page) {
+		super(model, page);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IViewReference#getSecondaryId()
+	 */
+	public String getSecondaryId() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IViewReference#getView(boolean)
+	 */
+	public IViewPart getView(boolean restore) {
+		return (IViewPart) getPart(restore);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IViewReference#isFastView()
+	 */
+	public boolean isFastView() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/LegacySelectionService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/LegacySelectionService.java
new file mode 100644
index 0000000..cbeae1c
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/LegacySelectionService.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.workbench.ui.api;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.INullSelectionListener;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+
+/**
+ * @since 3.3
+ * 
+ */
+public class LegacySelectionService implements ISelectionService {
+
+	ListenerList selectionListeners = new ListenerList(ListenerList.IDENTITY);
+	ListenerList postSelectionListeners = new ListenerList(
+			ListenerList.IDENTITY);
+
+	private IEclipseContext windowContext;
+
+	public LegacySelectionService(IEclipseContext context) {
+		windowContext = context;
+		windowContext.runAndTrack(new Runnable() {
+
+			public void run() {
+				fireSelectionChange();
+			}
+
+			/*
+			 * for debugging purposes only
+			 */
+			@Override
+			public String toString() {
+				return IServiceConstants.SELECTION;
+			}
+		});
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#addPostSelectionListener(org.eclipse
+	 * .ui.ISelectionListener)
+	 */
+	public void addPostSelectionListener(ISelectionListener listener) {
+		postSelectionListeners.add(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#addPostSelectionListener(java.lang.String
+	 * , org.eclipse.ui.ISelectionListener)
+	 */
+	public void addPostSelectionListener(String partId,
+			ISelectionListener listener) {
+		postSelectionListeners.add(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#addSelectionListener(org.eclipse.ui.
+	 * ISelectionListener)
+	 */
+	public void addSelectionListener(ISelectionListener listener) {
+		selectionListeners.add(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#addSelectionListener(java.lang.String,
+	 * org.eclipse.ui.ISelectionListener)
+	 */
+	public void addSelectionListener(String partId, ISelectionListener listener) {
+		selectionListeners.add(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.ISelectionService#getSelection()
+	 */
+	public ISelection getSelection() {
+		Object obj = windowContext.get(IServiceConstants.SELECTION);
+		if (obj instanceof ISelection) {
+			return (ISelection) obj;
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.ISelectionService#getSelection(java.lang.String)
+	 */
+	public ISelection getSelection(String partId) {
+		return getSelection();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#removePostSelectionListener(org.eclipse
+	 * .ui.ISelectionListener)
+	 */
+	public void removePostSelectionListener(ISelectionListener listener) {
+		postSelectionListeners.remove(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#removePostSelectionListener(java.lang
+	 * .String, org.eclipse.ui.ISelectionListener)
+	 */
+	public void removePostSelectionListener(String partId,
+			ISelectionListener listener) {
+		postSelectionListeners.remove(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#removeSelectionListener(org.eclipse.
+	 * ui.ISelectionListener)
+	 */
+	public void removeSelectionListener(ISelectionListener listener) {
+		selectionListeners.remove(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.ISelectionService#removeSelectionListener(java.lang.String
+	 * , org.eclipse.ui.ISelectionListener)
+	 */
+	public void removeSelectionListener(String partId,
+			ISelectionListener listener) {
+		selectionListeners.remove(listener);
+	}
+
+	protected void fireSelectionChange() {
+		fireSelection(getActivePart(), getSelection());
+		firePostSelection(getActivePart(), getSelection());
+	}
+
+	private IWorkbenchPart getActivePart() {
+		IEclipseContext currentActive = windowContext;
+		IEclipseContext child;
+		while ((child = (IEclipseContext) currentActive
+				.get(IContextConstants.ACTIVE_CHILD)) != null
+				&& child != currentActive) {
+			currentActive = child;
+		}
+		if (child != null) {
+			MPart p = (MPart) child.get(MPart.class.getName());
+			if (p == null)
+				return null;
+			Object object = p.getObject();
+			if (object == null)
+				return null;
+			if (object instanceof IWorkbenchPart)
+				return (IWorkbenchPart) p.getObject();
+		}
+		return null;
+	}
+
+	protected void fireSelection(final IWorkbenchPart part, final ISelection sel) {
+		Object[] array = selectionListeners.getListeners();
+		for (int i = 0; i < array.length; i++) {
+			final ISelectionListener l = (ISelectionListener) array[i];
+			if ((part != null && sel != null)
+					|| l instanceof INullSelectionListener) {
+
+				try {
+					l.selectionChanged(part, sel);
+				} catch (Exception e) {
+					WorkbenchPlugin.log(e);
+				}
+			}
+		}
+	}
+
+	protected void firePostSelection(final IWorkbenchPart part,
+			final ISelection sel) {
+		Object[] array = postSelectionListeners.getListeners();
+		for (int i = 0; i < array.length; i++) {
+			final ISelectionListener l = (ISelectionListener) array[i];
+			if ((part != null && sel != null)
+					|| l instanceof INullSelectionListener) {
+
+				try {
+					l.selectionChanged(part, sel);
+				} catch (Exception e) {
+					WorkbenchPlugin.log(e);
+				}
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledFolderLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledFolderLayout.java
new file mode 100644
index 0000000..d3e9093
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledFolderLayout.java
@@ -0,0 +1,18 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewStack;
+
+import org.eclipse.ui.IFolderLayout;
+
+public class ModeledFolderLayout extends ModeledPlaceholderFolderLayout
+		implements IFolderLayout {
+	public ModeledFolderLayout(MViewStack stackModel) {
+		super(stackModel);
+	}
+
+	public void addView(String viewId) {
+		MView viewModel = ModeledPageLayout.createViewModel(viewId, true);
+		folderModel.getChildren().add(viewModel);
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPageLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPageLayout.java
new file mode 100644
index 0000000..ac3f605
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPageLayout.java
@@ -0,0 +1,442 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.compatibility.LegacyView;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MEditorSashContainer;
+import org.eclipse.e4.ui.model.application.MEditorStack;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewSashContainer;
+import org.eclipse.e4.ui.model.application.MViewStack;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IPlaceholderFolderLayout;
+import org.eclipse.ui.IViewLayout;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+
+public class ModeledPageLayout implements IPageLayout {
+
+	private MPerspective perspModel;
+	private IPerspectiveDescriptor descriptor;
+	private ArrayList newWizardShortcuts = new ArrayList();
+	private ArrayList perspectiveShortcut = new ArrayList();
+	private ArrayList showInPart = new ArrayList();
+	private ArrayList showViewShortcut = new ArrayList();
+	private ArrayList actionSet = new ArrayList();
+
+	public ModeledPageLayout(MPerspective perspModel) {
+		// Create the editor area stack
+		this.perspModel = perspModel;
+
+		MEditorSashContainer esc = MApplicationFactory.eINSTANCE
+				.createEditorSashContainer();
+		MEditorStack editorArea = MApplicationFactory.eINSTANCE
+				.createEditorStack();
+		esc.getChildren().add(editorArea);
+		editorArea.setId(getEditorArea());
+		esc.setId(getEditorArea());
+
+		// editorArea.setName("Editor Area");
+
+		// perspModel.getChildren().add(esc);
+	}
+
+	public MPerspective getModel() {
+		return perspModel;
+	}
+
+	public void addActionSet(String actionSetId) {
+		actionSet.add(actionSetId);
+	}
+
+	public void addFastView(String viewId) {
+	}
+
+	public void addFastView(String viewId, float ratio) {
+	}
+
+	public void addNewWizardShortcut(String id) {
+		newWizardShortcuts.add(id);
+	}
+
+	public void addPerspectiveShortcut(String id) {
+		perspectiveShortcut.add(id);
+	}
+
+	public void addPlaceholder(String viewId, int relationship, float ratio,
+			String refId) {
+		insertView(viewId, relationship, ratio, refId, false, true);
+	}
+
+	public void addShowInPart(String id) {
+		showInPart.add(id);
+	}
+
+	public void addShowViewShortcut(String id) {
+		showViewShortcut.add(id);
+	}
+
+	public void addStandaloneView(String viewId, boolean showTitle,
+			int relationship, float ratio, String refId) {
+		MView viewModel = insertView(viewId, relationship, ratio, refId, true,
+				false);
+
+		// Set the state
+		if (viewModel != null) {
+			// viewModel.setShowTitle(showTitle);
+		}
+	}
+
+	public void addStandaloneViewPlaceholder(String viewId, int relationship,
+			float ratio, String refId, boolean showTitle) {
+		MView viewModel = insertView(viewId, relationship, ratio, refId, false,
+				false);
+
+		// Set the state
+		if (viewModel != null) {
+			// viewModel.setShowTitle(showTitle);
+		}
+	}
+
+	public void addView(String viewId, int relationship, float ratio,
+			String refId) {
+		insertView(viewId, relationship, ratio, refId, true, true);
+	}
+
+	public IFolderLayout createFolder(String folderId, int relationship,
+			float ratio, String refId) {
+		MViewStack stack = insertStack(folderId, relationship, ratio, refId,
+				true);
+		return new ModeledFolderLayout(stack);
+	}
+
+	public IPlaceholderFolderLayout createPlaceholderFolder(String folderId,
+			int relationship, float ratio, String refId) {
+		MViewStack Stack = insertStack(folderId, relationship, ratio, refId,
+				false);
+		return new ModeledPlaceholderFolderLayout(Stack);
+	}
+
+	public void setDescriptor(IPerspectiveDescriptor desc) {
+		descriptor = desc;
+	}
+
+	public IPerspectiveDescriptor getDescriptor() {
+		return descriptor;
+	}
+
+	public static String internalGetEditorArea() {
+		return IPageLayout.ID_EDITOR_AREA;
+	}
+
+	public String getEditorArea() {
+		return internalGetEditorArea();
+	}
+
+	public int getEditorReuseThreshold() {
+		return 0;
+	}
+
+	public IPlaceholderFolderLayout getFolderForView(String id) {
+		MPart view = findPart(perspModel, id);
+		if (view == null || !(view instanceof MView))
+			return null;
+
+		MUIElement stack = view.getParent();
+		if (stack == null || !(stack instanceof MViewStack))
+			return null;
+
+		return new ModeledPlaceholderFolderLayout((MViewStack) stack);
+	}
+
+	public IViewLayout getViewLayout(String id) {
+		MPart view = findPart(perspModel, id);
+		if (view == null || !(view instanceof MView))
+			return null;
+
+		return new ModeledViewLayout((MView) view);
+	}
+
+	public boolean isEditorAreaVisible() {
+		return true;
+	}
+
+	public boolean isFixed() {
+		return false;
+	}
+
+	public void setEditorAreaVisible(boolean showEditorArea) {
+	}
+
+	public void setEditorReuseThreshold(int openEditors) {
+	}
+
+	public void setFixed(boolean isFixed) {
+		// perspModel.setFixed(isFixed);
+	}
+
+	private static int plRelToSwt(int rel) {
+		switch (rel) {
+		case IPageLayout.BOTTOM:
+			return SWT.BOTTOM;
+		case IPageLayout.LEFT:
+			return SWT.LEFT;
+		case IPageLayout.RIGHT:
+			return SWT.RIGHT;
+		case IPageLayout.TOP:
+			return SWT.TOP;
+		default:
+			return 0;
+		}
+	}
+
+	public static MView createViewModel(String id, boolean visible) {
+		MView viewModel = MApplicationFactory.eINSTANCE.createView();
+
+		// HACK!! allow Contributed parts in a perspective
+		if (id.indexOf("platform:") >= 0) { //$NON-NLS-1$
+			viewModel.setURI(id);
+			viewModel.setName("Contrib View"); //$NON-NLS-1$
+			return viewModel;
+		}
+
+		viewModel.setURI(LegacyView.LEGACY_VIEW_URI);
+		viewModel.setId(id);
+
+		// Get the actual view name from the extension registry
+		IConfigurationElement[] views = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_VIEWS);
+		IConfigurationElement viewContribution = ExtensionUtils.findExtension(
+				views, id);
+		if (viewContribution != null) {
+			viewModel.setName(viewContribution.getAttribute("name")); //$NON-NLS-1$
+
+			// Convert the relative path into a bundle URI
+			String imagePath = viewContribution.getAttribute("icon"); //$NON-NLS-1$
+			if (imagePath != null) {
+				imagePath = imagePath.replace("$nl$", ""); //$NON-NLS-1$//$NON-NLS-2$
+				if (imagePath.charAt(0) != '/') {
+					imagePath = '/' + imagePath;
+				}
+				String bundleId = viewContribution.getContributor().getName();
+				String imageURI = "platform:/plugin/" + bundleId + imagePath; //$NON-NLS-1$
+				viewModel.setIconURI(imageURI);
+			}
+		} else
+			viewModel.setName(id); // No registered view, create error part?
+
+		// sets its visibility (false == placeholder)
+		viewModel.setVisible(visible);
+
+		return viewModel;
+	}
+
+	public static MViewStack createStack(String id, boolean visible) {
+		MViewStack newStack = MApplicationFactory.eINSTANCE.createViewStack();
+		newStack.setId(id);
+		newStack.setVisible(visible);
+		return newStack;
+	}
+
+	private MView insertView(String viewId, int relationship, float ratio,
+			String refId, boolean visible, boolean withStack) {
+		MUIElement refModel = findPart(perspModel, refId);
+		if (refModel == null || !(refModel instanceof MPart))
+			return null;
+
+		MView viewModel = createViewModel(viewId, visible);
+
+		if (withStack) {
+			String stackId = viewId + "MStack"; // Default id...basically unusable //$NON-NLS-1$
+			MViewStack stack = insertStack(stackId, relationship, ratio, refId,
+					visible);
+			stack.getChildren().add(viewModel);
+		} else {
+			insert(viewModel, (MPart) refModel, plRelToSwt(relationship), ratio);
+		}
+
+		return viewModel;
+	}
+
+	private MViewStack insertStack(String stackId, int relationship,
+			float ratio, String refId, boolean visible) {
+		MUIElement refModel = findPart(perspModel, refId);
+		if (refModel == null || !(refModel instanceof MPart))
+			return null;
+
+		// If the 'refModel' is -not- a stack then find one
+		// This covers cases where the defining layout is adding
+		// Views relative to other views and relying on the stacks
+		// being automatically created.
+		if (!(refModel instanceof MViewStack)) {
+			while (refModel.getParent() != null) {
+				refModel = refModel.getParent();
+				if (refModel instanceof MViewStack)
+					break;
+			}
+			if (!(refModel instanceof MViewStack))
+				return null;
+		}
+
+		MViewStack stack = createStack(stackId, visible);
+		insert(stack, (MPart) refModel, plRelToSwt(relationship), ratio);
+
+		return stack;
+	}
+
+	public static void replace(MUIElement relTo,
+			MElementContainer<MUIElement> newParent) {
+		if (relTo == null || newParent == null)
+			return;
+
+		MElementContainer<MUIElement> parent = relTo.getParent();
+		if (parent == null)
+			return;
+
+		List kids = parent.getChildren();
+		if (kids == null)
+			return;
+
+		kids.add(kids.indexOf(relTo), newParent);
+		kids.remove(relTo);
+	}
+
+	public static void insertParent(MElementContainer<MUIElement> newParent,
+			MUIElement relTo) {
+		if (newParent == null || relTo == null)
+			return;
+
+		MPart curParent = (MPart) relTo.getParent();
+		if (curParent != null) {
+			replace(relTo, newParent);
+		}
+
+		// Move the child under the new parent
+		newParent.getChildren().add(relTo);
+	}
+
+	public static void insert(MUIElement toInsert, MUIElement relTo,
+			int swtSide, int ratio) {
+		if (toInsert == null || relTo == null)
+			return;
+
+		MElementContainer<MUIElement> relParent = relTo.getParent();
+
+		boolean isStack = true;
+
+		// Create the new sash if we're going to need one
+		MViewSashContainer newSash = null;
+		if ((swtSide == SWT.TOP || swtSide == SWT.BOTTOM) && !isStack) {
+			newSash = MApplicationFactory.eINSTANCE.createViewSashContainer();
+			String label = "Vertical Sash[" + toInsert.getId() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+			newSash.setId(label);
+			newSash.setHorizontal(false);
+		} else if ((swtSide == SWT.LEFT || swtSide == SWT.RIGHT) && !isStack) {
+			newSash = MApplicationFactory.eINSTANCE.createViewSashContainer();
+			String label = "Horizontal Sash[" + toInsert.getId() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+			newSash.setId(label);
+			newSash.setHorizontal(true);
+		}
+
+		List parts;
+		if (newSash == null && relParent != null) {
+			parts = relParent.getChildren();
+		} else {
+			MUIElement vscElement = newSash;
+			MElementContainer<MUIElement> container = (MElementContainer<MUIElement>) vscElement;
+			insertParent(container, relTo);
+			parts = newSash.getChildren();
+
+			List<Integer> weights = newSash.getWeights();
+			weights.add(ratio);
+			weights.add(100 - ratio);
+		}
+
+		// Insert the part in the correct location
+		int index = parts.indexOf(relTo);
+		if (swtSide == SWT.BOTTOM || swtSide == SWT.RIGHT) {
+			index++;
+
+		}
+
+		parts.add(index, toInsert);
+	}
+
+	public static void insert(MUIElement toInsert, MUIElement relTo,
+			int swtSide, float ratio) {
+		int pct = (int) (ratio * 100);
+		insert(toInsert, relTo, swtSide, pct);
+	}
+
+	public static MUIElement findElementById(MUIElement element, String id) {
+		if (id == null || id.length() == 0)
+			return null;
+
+		// is it me?
+		if (id.equals(element.getId()))
+			return element;
+
+		// Recurse if this is a container
+		if (element instanceof MElementContainer) {
+			EList<MUIElement> children = ((MElementContainer<MUIElement>) element)
+					.getChildren();
+			MUIElement foundElement = null;
+			for (MUIElement childME : children) {
+				foundElement = findElementById(childME, id);
+				if (foundElement != null)
+					return foundElement;
+			}
+		}
+
+		return null;
+	}
+
+	public static MPart findPart(MUIElement toSearch, String id) {
+		if (toSearch == null)
+			return null;
+
+		MUIElement found = findElementById(toSearch, id);
+		if (found instanceof MPart)
+			return (MPart) found;
+
+		return null;
+	}
+
+	/**
+	 * @return
+	 */
+	public ArrayList getNewWizardShortcuts() {
+		return newWizardShortcuts;
+	}
+
+	/**
+	 * @return
+	 */
+	public ArrayList getShowViewShortcuts() {
+		return showViewShortcut;
+	}
+
+	/**
+	 * @return
+	 */
+	public ArrayList getPerspectiveShortcuts() {
+		return perspectiveShortcut;
+	}
+
+	/**
+	 * @return
+	 */
+	public ArrayList getShowInPartIds() {
+		return showInPart;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPlaceholderFolderLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPlaceholderFolderLayout.java
new file mode 100644
index 0000000..e59b2f7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPlaceholderFolderLayout.java
@@ -0,0 +1,30 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewStack;
+
+import org.eclipse.ui.IPlaceholderFolderLayout;
+
+public class ModeledPlaceholderFolderLayout implements IPlaceholderFolderLayout {
+
+	protected MViewStack folderModel;
+
+	public ModeledPlaceholderFolderLayout(MViewStack stackModel) {
+		folderModel = stackModel;
+	}
+
+	public void addPlaceholder(String viewId) {
+		MView viewModel = ModeledPageLayout.createViewModel(viewId, false);
+		folderModel.getChildren().add(viewModel);
+	}
+
+	public String getProperty(String id) {
+		Object propVal = null;
+		return propVal == null ? "" : propVal.toString(); //$NON-NLS-1$
+	}
+
+	public void setProperty(String id, String value) {
+		// folderModel.setProperty(id, value);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledViewLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledViewLayout.java
new file mode 100644
index 0000000..4d452b3
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledViewLayout.java
@@ -0,0 +1,39 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import org.eclipse.e4.ui.model.application.MView;
+
+import org.eclipse.ui.IViewLayout;
+
+public class ModeledViewLayout implements IViewLayout {
+
+	// private MContributedPart viewME;
+
+	public ModeledViewLayout(MView view) {
+		// viewME = view;
+	}
+
+	public boolean getShowTitle() {
+		return true;// viewME.getShowTitle();
+	}
+
+	public boolean isCloseable() {
+		return true;// viewME.isCloseable();
+	}
+
+	public boolean isMoveable() {
+		return true;// viewME.isMoveable();
+	}
+
+	public boolean isStandalone() {
+		return false;// viewME.isStandAlone();
+	}
+
+	public void setCloseable(boolean closeable) {
+		// viewME.setCloseable(closeable);
+	}
+
+	public void setMoveable(boolean moveable) {
+		// viewME.setMoveable(moveable);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/ActionSet.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/ActionSet.java
new file mode 100644
index 0000000..92f8dda
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/ActionSet.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.workbench.ui.menus;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MHandledItem;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MMenuItem;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+
+/**
+ * 
+ */
+public class ActionSet {
+	private IEclipseContext context;
+	private IConfigurationElement config;
+	private boolean visible = true;
+
+	private List<MHandledItem> items = new ArrayList<MHandledItem>();
+
+	public ActionSet(IEclipseContext context, IConfigurationElement element) {
+		this.context = context;
+		config = element;
+	}
+
+	public boolean merge(MMenu menu) {
+		IConfigurationElement[] menus = config
+				.getChildren(IWorkbenchRegistryConstants.TAG_MENU);
+		for (IConfigurationElement element : menus) {
+			addMenu(menu, element);
+		}
+		IConfigurationElement[] actions = config
+				.getChildren(IWorkbenchRegistryConstants.TAG_ACTION);
+		for (IConfigurationElement element : actions) {
+			addAction(menu, element);
+		}
+		return true;
+	}
+
+	/**
+	 * @param menu
+	 * @param element
+	 */
+	private void addAction(MMenu menu, IConfigurationElement element) {
+		final String elementId = MenuHelper.getId(element);
+		String path = element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_MENUBAR_PATH);
+		if (path == null) {
+			return;
+		}
+		Path menuPath = new Path(path);
+		MMenu parentMenu = findMenuFromPath(menu, menuPath, 0);
+		if (parentMenu == null) {
+			Activator
+					.trace(
+							Policy.DEBUG_MENUS,
+							"Failed to find menu for action " + elementId + ':' + path, null); //$NON-NLS-1$
+			return;
+		}
+		int idx = MenuHelper.indexForId(parentMenu, menuPath.lastSegment());
+		if (idx == -1) {
+			idx = MenuHelper.indexForId(parentMenu,
+					IWorkbenchActionConstants.MB_ADDITIONS);
+		}
+		if (idx == -1) {
+			Activator
+					.trace(
+							Policy.DEBUG_MENUS,
+							"Failed to find group for action " + elementId + ':' + path, null); //$NON-NLS-1$
+			return;
+		}
+		MMenuItem item = createActionElement(element);
+		parentMenu.getChildren().add(idx, item);
+	}
+
+	/**
+	 * @param menu
+	 * @param element
+	 */
+	private void addMenu(MMenu menu, IConfigurationElement element) {
+		final String elementId = MenuHelper.getId(element);
+		String path = element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_PATH);
+		if (path == null || path.length() == 0) {
+			path = IWorkbenchActionConstants.MB_ADDITIONS;
+		}
+		Path menuPath = new Path(path);
+		MMenu parentMenu = menu;
+		if (menuPath.segmentCount() > 1) {
+			parentMenu = findMenuFromPath(menu, menuPath, 0);
+		}
+		if (parentMenu == menu) {
+			Activator
+					.trace(
+							Policy.DEBUG_MENUS,
+							"Using parent menu for menu " + elementId + ':' + path, null); //$NON-NLS-1$
+		}
+		String id = MenuHelper.getId(element);
+		MMenuItem item = null;
+		final int itemIdx = MenuHelper.indexForId(parentMenu, id);
+		if (itemIdx == -1) {
+			int idx = MenuHelper.indexForId(parentMenu, menuPath.lastSegment());
+			if (idx == -1) {
+				idx = MenuHelper.indexForId(parentMenu,
+						IWorkbenchActionConstants.MB_ADDITIONS);
+			}
+			if (idx == -1) {
+				Activator
+						.trace(
+								Policy.DEBUG_MENUS,
+								"Failed to find group for menu " + elementId + ':' + path, null); //$NON-NLS-1$
+				return;
+			}
+			item = createMenuElement(element);
+			parentMenu.getChildren().add(idx + 1, item);
+		} else {
+			item = parentMenu.getChildren().get(itemIdx);
+		}
+		processGroups(item, element);
+	}
+
+	/**
+	 * @param menu
+	 * @param element
+	 */
+	private void processGroups(MMenu menu, IConfigurationElement element) {
+		IConfigurationElement[] children = element.getChildren();
+		for (IConfigurationElement child : children) {
+			String name = child
+					.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+			if (MenuHelper.indexForId(menu, name) == -1) {
+				MenuHelper.addSeparator(menu, name, true);
+			}
+		}
+	}
+
+	/**
+	 * @param menu
+	 * @param path
+	 * @return
+	 */
+	private MMenu findMenuFromPath(MMenu menu, Path menuPath, int segment) {
+		int idx = MenuHelper.indexForId(menu, menuPath.segment(segment));
+		if (idx == -1) {
+			if (segment + 1 < menuPath.segmentCount()
+					|| !menuPath.hasTrailingSeparator()) {
+				return null;
+			}
+			return menu;
+		}
+		MMenuItem item = menu.getChildren().get(idx);
+		if (item.getChildren().size() == 0) {
+			if (segment + 1 == menuPath.segmentCount()) {
+				return menu;
+			} else {
+				return null;
+			}
+		}
+		return findMenuFromPath(item, menuPath, segment + 1);
+	}
+
+	private MMenuItem createMenuElement(IConfigurationElement element) {
+		String imagePath = MenuHelper.getImageUrl(MenuHelper
+				.getIconDescriptor(element));
+		String id = MenuHelper.getId(element);
+		String label = MenuHelper.getLabel(element);
+		MMenuItem item = MenuHelper.createMenuItem(context, label, imagePath,
+				id, null);
+		return item;
+	}
+
+	private MMenuItem createActionElement(IConfigurationElement element) {
+		String imagePath = MenuHelper.getImageUrl(MenuHelper
+				.getIconDescriptor(element));
+		String cmdId = MenuHelper.getActionSetCommandId(element);
+		String id = MenuHelper.getId(element);
+		String label = MenuHelper.getLabel(element);
+		// int style = MenuHelper.getStyle(element);
+		// if (style == CommandContributionItem.STYLE_PULLDOWN) {
+		// IWorkbenchWindow window = (IWorkbenchWindow) context
+		// .get(IWorkbenchWindow.class.getName());
+		// // we need to treat a pulldown action as a renderer, since the
+		// // action
+		// // itself contains the rendering code
+		// ActionDescriptor desc = new ActionDescriptor(element,
+		// ActionDescriptor.T_WORKBENCH_PULLDOWN, window);
+		// final ActionContributionItem item = new ActionContributionItem(desc
+		// .getAction());
+		// MMenuItemRenderer r = WorkbenchFactory.eINSTANCE
+		// .createMMenuItemRenderer();
+		//			r.setId(item.getId() == null ? "item:" + id : item.getId()); //$NON-NLS-1$
+		// r.setRenderer(item);
+		// return r;
+		// }
+		if (label == null) {
+			if (cmdId == null) {
+				label = "none:" + id; //$NON-NLS-1$
+			} else {
+				ICommandService cs = (ICommandService) context
+						.get(ICommandService.class.getName());
+				Command cmd = cs.getCommand(cmdId);
+				if (cmd.isDefined()) {
+					try {
+						label = cmd.getName();
+					} catch (NotDefinedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+
+		MMenuItem item = MenuHelper.createMenuItem(context, label, imagePath,
+				id, cmdId);
+		// items.add(item);
+		return item;
+	}
+
+	public void setVisible(boolean v) {
+		if (v == visible) {
+			return;
+		}
+		visible = v;
+		for (MHandledItem item : items) {
+			item.setVisible(visible);
+		}
+	}
+
+	public String getId() {
+		return MenuHelper.getId(config);
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuContribution.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuContribution.java
new file mode 100644
index 0000000..baf85e5
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuContribution.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.workbench.ui.menus;
+
+import java.util.ArrayList;
+import java.util.Map;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MMenuItem;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.e4.workbench.ui.internal.Trackable;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyEvalContext;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.internal.menus.MenuLocationURI;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.util.Util;
+
+/**
+ * @since 3.3
+ * 
+ */
+public class MenuContribution {
+	/**
+	 * 
+	 */
+	private static final String WINDOW_IS_CLOSED = "MenuContribution.window.isClosed"; //$NON-NLS-1$
+	private IConfigurationElement config;
+	private IEclipseContext context;
+	private MenuLocationURI uri;
+	private MMenu model;
+	private ArrayList<TrackVisible> trackers = new ArrayList<TrackVisible>();
+
+	public MenuContribution(IEclipseContext context,
+			IConfigurationElement element) {
+		this.context = context;
+		window = (IWorkbenchWindow) context.get(IWorkbenchWindow.class
+				.getName());
+		context.set(WINDOW_IS_CLOSED, Boolean.FALSE);
+		config = element;
+		uri = new MenuLocationURI(config
+				.getAttribute(IWorkbenchRegistryConstants.TAG_LOCATION_URI));
+		window.getWorkbench().addWindowListener(new IWindowListener() {
+
+			public void windowOpened(IWorkbenchWindow window) {
+				// TODO Auto-generated method stub
+
+			}
+
+			public void windowDeactivated(IWorkbenchWindow window) {
+				// TODO Auto-generated method stub
+
+			}
+
+			public void windowClosed(IWorkbenchWindow window) {
+				if (window == MenuContribution.this.window) {
+					cleanUp();
+				}
+			}
+
+			public void windowActivated(IWorkbenchWindow window) {
+				// TODO Auto-generated method stub
+
+			}
+		});
+	}
+
+	public MenuLocationURI getURI() {
+		return uri;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return MenuContribution.class.getName() + ": " //$NON-NLS-1$
+				+ getURI();
+	}
+
+	public boolean merge(MMenu menu) {
+		String locationID = getURI().getPath();
+		if (locationID.equals(menu.getId())) {
+			loadModel();
+			return mergeModel(menu);
+		}
+		return false;
+	}
+
+	private boolean mergeModel(MMenu menu) {
+		int idx = getInsertionIndex(menu);
+		if (idx == -1) {
+			return false;
+		}
+		return mergeModel(idx, menu, model);
+	}
+
+	private boolean mergeModel(int idx, MMenu menu, MMenu toInsert) {
+		EList<MMenuItem> items = menu.getChildren();
+		MMenuItem[] modelItems = toInsert.getChildren().toArray(
+				new MMenuItem[toInsert.getChildren().size()]);
+		for (int i = 0; i < modelItems.length; i++) {
+			MMenuItem modelItem = modelItems[i];
+			if (modelItem.getChildren().size() > 0) {
+				int tmpIdx = MenuHelper.indexForId(menu, modelItem.getId());
+				if (tmpIdx == -1) {
+					items.add(idx++, modelItem);
+				} else {
+					mergeModel(0, items.get(tmpIdx), modelItem);
+				}
+			} else {
+				items.add(idx++, modelItem);
+			}
+		}
+		return true;
+
+	}
+
+	private int getInsertionIndex(MMenu menu) {
+		int additionsIndex = -1;
+		String query = getURI().getQuery();
+		if (query.length() == 0 || query.equals("after=additions")) { //$NON-NLS-1$
+			additionsIndex = MenuHelper.indexForId(menu, "additions"); //$NON-NLS-1$
+			if (additionsIndex == -1) {
+				additionsIndex = menu.getChildren().size();
+			} else {
+				additionsIndex++;
+			}
+		} else {
+			String[] queryParts = Util.split(query, '=');
+			if (queryParts.length > 1 && queryParts[1].length() > 0) {
+				additionsIndex = MenuHelper.indexForId(menu, queryParts[1]);
+				if (additionsIndex != -1 && queryParts[0].equals("after")) //$NON-NLS-1$
+					additionsIndex++;
+			}
+		}
+		return additionsIndex;
+	}
+
+	private void loadModel() {
+		model = MApplicationFactory.eINSTANCE.createMenu();
+		loadModel(config, model);
+	}
+
+	private void loadModel(IConfigurationElement menuElement, MMenu menu) {
+		IConfigurationElement[] children = menuElement.getChildren();
+		for (IConfigurationElement element : children) {
+			String elementType = element.getName();
+			if (IWorkbenchRegistryConstants.TAG_COMMAND.equals(elementType)) {
+				MMenuItem item = createCommandElement(element);
+				menu.getChildren().add(item);
+			} else if (IWorkbenchRegistryConstants.TAG_MENU.equals(elementType)) {
+				MMenuItem item = createMenuElement(element);
+				menu.getChildren().add(item);
+			} else if (IWorkbenchRegistryConstants.TAG_SEPARATOR
+					.equals(elementType)) {
+				MenuHelper.addSeparator(menu, MenuHelper.getId(element), true);
+			} else if (IWorkbenchRegistryConstants.TAG_DYNAMIC
+					.equals(elementType)) {
+				addRenderer(menu, element);
+			}
+		}
+	}
+
+	/**
+	 * @param menu
+	 * @param element
+	 */
+	private void addRenderer(MMenu menu, IConfigurationElement element) {
+		// ContributionItem i = (ContributionItem) Util
+		// .safeLoadExecutableExtension(element,
+		// IWorkbenchRegistryConstants.ATT_CLASS,
+		// ContributionItem.class);
+		// if (i instanceof IWorkbenchContribution) {
+		// ((IWorkbenchContribution) i).initialize(window);
+		// }
+		// MMenuItemRenderer renderer = MenuHelper.addMenuRenderer(context,
+		// menu,
+		// i);
+		// associateVisibleWhen(element, renderer);
+	}
+
+	private IWorkbenchWindow window;
+
+	/**
+	 * @param element
+	 * @return
+	 */
+	private MMenuItem createMenuElement(IConfigurationElement element) {
+		String imagePath = MenuHelper.getImageUrl(MenuHelper
+				.getIconDescriptor(element));
+		String id = MenuHelper.getId(element);
+		String label = MenuHelper.getLabel(element);
+		MMenuItem item = MenuHelper.createMenuItem(context, label, imagePath,
+				id, null);
+		loadModel(element, item);
+		return item;
+	}
+
+	private MMenuItem createCommandElement(IConfigurationElement element) {
+		String imagePath = MenuHelper.getImageUrl(MenuHelper
+				.getIconDescriptor(element));
+		String cmdId = MenuHelper.getCommandId(element);
+		String id = MenuHelper.getId(element);
+		String label = MenuHelper.getLabel(element);
+		ICommandService cs = (ICommandService) context
+				.get(ICommandService.class.getName());
+		Command cmd = cs.getCommand(cmdId);
+		if (label == null) {
+			if (cmd.isDefined()) {
+				try {
+					label = cmd.getName();
+				} catch (NotDefinedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		final MMenuItem item = MenuHelper.createMenuItem(context, label,
+				imagePath, id, cmdId);
+		final Map<String, String> parms = MenuHelper.getParameters(element);
+		if (!parms.isEmpty()) {
+			// final EList<MParameter> modelParms = item.getParameters();
+			// for (Map.Entry<String, String> entry : parms.entrySet()) {
+			// MParameter p = ApplicationFactory.eINSTANCE.createMParameter();
+			// p.setName(entry.getKey());
+			// p.setValue(entry.getValue());
+			// modelParms.add(p);
+			// }
+		}
+
+		associateVisibleWhen(element, item);
+		return item;
+	}
+
+	class TrackVisible extends Trackable {
+		private MMenuItem item;
+		private LegacyEvalContext legacyEvalContext;
+		private Expression visWhen;
+		boolean participating = true;
+
+		public TrackVisible(MMenuItem item, IEclipseContext context,
+				Expression visWhen) {
+			super(context);
+			this.item = item;
+			this.legacyEvalContext = new LegacyEvalContext(trackingContext);
+			this.visWhen = visWhen;
+		}
+
+		public void run() {
+			if (!participating) {
+				return;
+			}
+			trackingContext.get(WINDOW_IS_CLOSED);
+			boolean visible = true;
+			try {
+				visible = visWhen.evaluate(legacyEvalContext) != EvaluationResult.FALSE;
+			} catch (CoreException e) {
+				Activator.trace(Policy.DEBUG_MENUS,
+						"Failed to evaluate visibleWhen", e); //$NON-NLS-1$
+			}
+			Activator.trace(Policy.DEBUG_MENUS,
+					"visibleWhen set to " + visible, null); //$NON-NLS-1$
+
+			item.setVisible(visible);
+		}
+	}
+
+	/**
+	 * @param element
+	 * @param item
+	 */
+	private void associateVisibleWhen(final IConfigurationElement element,
+			final MMenuItem item) {
+		IConfigurationElement[] visibleWhen = element
+				.getChildren(IWorkbenchRegistryConstants.TAG_VISIBLE_WHEN);
+		if (visibleWhen.length > 0) {
+			IConfigurationElement[] visibleChild = visibleWhen[0].getChildren();
+			if (visibleChild.length > 0) {
+				try {
+					final Expression visWhen = ExpressionConverter.getDefault()
+							.perform(visibleChild[0]);
+					TrackVisible runnable = new TrackVisible(item, context,
+							visWhen);
+					trackers.add(runnable);
+					context.runAndTrack(runnable);
+				} catch (CoreException e) {
+					Activator.trace(Policy.DEBUG_MENUS,
+							"Failed to parse visibleWhen", e); //$NON-NLS-1$
+				}
+			}
+		}
+	}
+
+	void cleanUp() {
+		for (TrackVisible tracker : trackers) {
+			tracker.participating = false;
+		}
+		context.set(WINDOW_IS_CLOSED, Boolean.TRUE);
+		trackers.clear();
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuHelper.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuHelper.java
new file mode 100644
index 0000000..a68b5f4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuHelper.java
@@ -0,0 +1,737 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.workbench.ui.menus;
+
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MCommand;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MMenuItem;
+import org.eclipse.e4.ui.model.application.MToolBar;
+import org.eclipse.e4.ui.model.application.MToolItem;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.commands.ICommandImageService;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.internal.Workbench;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.menus.CommandContributionItem;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+public class MenuHelper {
+
+	public static final String ACTION_SET_CMD_PREFIX = "AS::"; //$NON-NLS-1$
+	public static final String MAIN_MENU_ID = "org.eclipse.ui.main.menu"; //$NON-NLS-1$
+	private static Field urlField;
+
+	public static void loadMainMenu(IEclipseContext context, MMenu menuModel,
+			MenuManager barManager) {
+		// traceMenuModel(menuModel);
+		processMenuManager(context, menuModel, barManager.getItems());
+		MenuContribution[] contributions = loadMenuContributions(context);
+		processMenuContributions(context, menuModel, contributions);
+		// processActionSets(context, menuModel);
+	}
+
+	/**
+	 * @param context
+	 * @param menuModel
+	 */
+	public static ActionSet[] processActionSets(IEclipseContext context,
+			MMenu menuModel) {
+		ActionSet[] sets = loadActionSets(context, menuModel);
+		for (ActionSet actionSet : sets) {
+			actionSet.merge(menuModel);
+		}
+		return sets;
+	}
+
+	/**
+	 * @param context
+	 * @param menuModel
+	 */
+	private static ActionSet[] loadActionSets(IEclipseContext context,
+			MMenu menuModel) {
+		ArrayList<ActionSet> contributions = new ArrayList<ActionSet>();
+		IConfigurationElement[] elements = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+		for (IConfigurationElement element : elements) {
+			contributions.add(new ActionSet(context, element));
+		}
+		return contributions.toArray(new ActionSet[contributions.size()]);
+	}
+
+	public static int indexForId(MMenu parentMenu, String id) {
+		if (id == null || id.length() == 0) {
+			return -1;
+		}
+		int i = 0;
+		for (MMenuItem item : parentMenu.getChildren()) {
+			if (id.equals(item.getId())) {
+				return i;
+			}
+			i++;
+		}
+		return -1;
+	}
+
+	public static String getActionSetCommandId(IConfigurationElement element) {
+		String id = MenuHelper.getDefinitionId(element);
+		if (id != null) {
+			return id;
+		}
+		id = MenuHelper.getId(element);
+		String actionSetId = null;
+		Object obj = element.getParent();
+		while (obj instanceof IConfigurationElement && actionSetId == null) {
+			IConfigurationElement parent = (IConfigurationElement) obj;
+			if (parent.getName().equals(
+					IWorkbenchRegistryConstants.TAG_ACTION_SET)) {
+				actionSetId = MenuHelper.getId(parent);
+			}
+			obj = parent.getParent();
+		}
+		return ACTION_SET_CMD_PREFIX + actionSetId + '/' + id;
+	}
+
+	/**
+	 * @param context
+	 * @param menuModel
+	 */
+	static void processMenuContributions(IEclipseContext context,
+			MMenu menuBar, MenuContribution[] contributions) {
+		HashSet<MenuContribution> processedContributions = new HashSet<MenuContribution>();
+		int size = -1;
+		while (size != processedContributions.size()) {
+			size = processedContributions.size();
+			for (MenuContribution contribution : contributions) {
+				if (!processedContributions.contains(contribution)) {
+					if (contribution.merge(menuBar)) {
+						processedContributions.add(contribution);
+					}
+				}
+			}
+		}
+		// now, what about sub menus
+		EList<MMenuItem> items = menuBar.getChildren();
+		for (MMenuItem menuItem : items) {
+			if (menuItem.getChildren().size() > 0) {
+				processMenuContributions(context, menuItem, contributions);
+			}
+		}
+	}
+
+	/**
+	 * @param context
+	 */
+	static MenuContribution[] loadMenuContributions(IEclipseContext context) {
+		ArrayList<MenuContribution> contributions = new ArrayList<MenuContribution>();
+		IConfigurationElement[] elements = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_MENUS);
+		for (IConfigurationElement element : elements) {
+			if (element.getName().equals(
+					IWorkbenchRegistryConstants.PL_MENU_CONTRIBUTION)) {
+				contributions.add(new MenuContribution(context, element));
+			}
+		}
+		return contributions
+				.toArray(new MenuContribution[contributions.size()]);
+	}
+
+	static abstract class ProcessItem {
+		static final ProcessItem MENU = new ProcessMenuItem();
+		static final ProcessItem TOOLBAR = new ProcessToolBarItem();
+
+		public void process(IEclipseContext context,
+				CommandContributionItem cci, Object modelParent) {
+			String id = cci.getCommand().getId();
+			ICommandService cs = (ICommandService) context
+					.get(ICommandService.class.getName());
+			Command cmd = cs.getCommand(id);
+			if (cmd.isDefined()) {
+				ICommandImageService cis = (ICommandImageService) context
+						.get(ICommandImageService.class.getName());
+				String imageURL = getImageUrl(cis.getImageDescriptor(cmd
+						.getId(), ICommandImageService.TYPE_DEFAULT));
+				try {
+					addModelItem(context, modelParent, cmd.getName(), imageURL,
+							cci.getId(), id);
+				} catch (NotDefinedException e) {
+					// This should not happen
+					e.printStackTrace();
+				}
+			} else {
+				addModelItem(context, modelParent,
+						"unloaded:" + id, null, cci.getId(), id); //$NON-NLS-1$
+			}
+		}
+
+		public void process(IEclipseContext context,
+				ActionContributionItem aci, Object modelParent) {
+			IAction action = aci.getAction();
+			String commandID = action.getActionDefinitionId();
+			if (commandID == null)
+				commandID = aci.getId();
+			if (commandID == null) {
+				commandID = action.getId();
+			}
+			if (commandID == null) {
+				// last resort, this is goofy
+				commandID = "GEN::" + System.identityHashCode(aci); //$NON-NLS-1$
+			}
+
+			if (action.getActionDefinitionId() == null && commandID != null) {
+				// check that we have a command; create it if necessary
+				Workbench legacyWB = (Workbench) context.get(Workbench.class
+						.getName());
+				String label = action.getText();
+				if (label == null) {
+					label = action.getToolTipText();
+				}
+				if (label == null) {
+					label = "label for " + commandID; //$NON-NLS-1$
+				}
+				legacyWB.addCommand(commandID, label);
+
+				// create handler
+				IHandler handler = new ActionHandler(action);
+				LegacyHandlerService.registerLegacyHandler(context, commandID,
+						commandID, handler, null);
+
+				// update action definition if needed
+				if (action.getActionDefinitionId() == null)
+					action.setActionDefinitionId(commandID);
+			}
+			addModelItem(context, modelParent, action, aci.getId());
+		}
+
+		public void addModelItem(IEclipseContext context, Object modelParent,
+				IAction action, String id) {
+			String imageURL = getImageUrl(action.getImageDescriptor());
+
+			addModelItem(context, modelParent, action.getText(), imageURL, id,
+					action.getActionDefinitionId());
+		}
+
+		public abstract void addModelItem(IEclipseContext context,
+				Object modelParent, String label, String imageURL, String id,
+				String cmdId);
+
+		static class ProcessToolBarItem extends ProcessItem {
+
+			@Override
+			public void addModelItem(IEclipseContext context,
+					Object modelParent, String label, String imageURL,
+					String id, String cmdId) {
+				MToolItem newItem = createToolbarItem(context, label, imageURL,
+						id, cmdId);
+				MToolBar tbModel = (MToolBar) modelParent;
+				tbModel.getChildren().add(newItem);
+			}
+
+		}
+
+		static class ProcessMenuItem extends ProcessItem {
+			@Override
+			public void addModelItem(IEclipseContext context,
+					Object modelParent, String label, String imageURL,
+					String id, String cmdId) {
+				MMenu menu = (MMenu) modelParent;
+				addMenuItem(context, menu, label, null, imageURL, id, cmdId);
+			}
+		}
+	}
+
+	/**
+	 * @param menu
+	 * @param manager
+	 */
+	public static void processMenuManager(IEclipseContext context, MMenu menu,
+			IContributionItem[] items) {
+
+		if (items.length == 0) {
+			addMenuItem(context, menu, "Test Item", null, null, //$NON-NLS-1$
+					"test.id", "test.action.id"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		for (int i = 0; i < items.length; i++) {
+			IContributionItem item = items[i];
+			if (item instanceof MenuManager) {
+				MenuManager m = (MenuManager) item;
+				MMenuItem menu1 = addMenu(context, menu, m.getMenuText(), null,
+						null, m.getId(), null);
+				processMenuManager(context, menu1, m.getItems());
+			} else if (item instanceof ActionContributionItem) {
+				ActionContributionItem aci = (ActionContributionItem) item;
+				if ((aci.getAction().getStyle() | IAction.AS_DROP_DOWN_MENU) == 0) {
+					ProcessItem.MENU.process(context, aci, menu);
+				} else {
+					// addMenuRenderer(context, menu, item);
+				}
+			} else if (item instanceof CommandContributionItem) {
+				CommandContributionItem cci = (CommandContributionItem) item;
+				ProcessItem.MENU.process(context, cci, menu);
+			} else if (item instanceof Separator) {
+				addSeparator(menu, item.getId(), true);
+			} else if (item instanceof GroupMarker) {
+				addSeparator(menu, item.getId(), false);
+			} else {
+				Activator.trace(Policy.DEBUG_MENUS,
+						"ICI: " + item.getClass().getName(), null); //$NON-NLS-1$
+				// addMenuRenderer(context, menu, item);
+			}
+		}
+	}
+
+	/**
+	 * @param context
+	 * @param menu
+	 * @param item
+	 */
+	// public static MMenuItemRenderer addMenuRenderer(IEclipseContext context,
+	// MMenu menu, IContributionItem item) {
+	// MMenuItemRenderer r = WorkbenchFactory.eINSTANCE
+	// .createMMenuItemRenderer();
+	//		r.setId(item.getId() == null ? "item:" + menu.getId() : item.getId()); //$NON-NLS-1$
+	// r.setRenderer(item);
+	// menu.getChildren().add(r);
+	// return r;
+	// }
+	//
+	// public static MToolItemRenderer addToolRenderer(IEclipseContext context,
+	// MToolBar bar, IContributionItem item) {
+	// MToolItemRenderer r = WorkbenchFactory.eINSTANCE
+	// .createMToolItemRenderer();
+	//		r.setId(item.getId() == null ? "item:" + bar.getId() : item.getId()); //$NON-NLS-1$
+	// r.setRenderer(item);
+	// bar.getChildren().add(r);
+	// return r;
+	// }
+
+	/**
+	 * @param menu
+	 * @param manager
+	 */
+	public static void processToolbarManager(IEclipseContext context,
+			MToolBar tbModel, IContributionItem[] items) {
+
+		if (items.length == 0) {
+			addToolbarItem(tbModel, "Test Item", null, null, //$NON-NLS-1$
+					"test.id", "test.action.id"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		for (int i = 0; i < items.length; i++) {
+			IContributionItem item = items[i];
+			if (item instanceof MenuManager) {
+				Activator
+						.trace(Policy.DEBUG_MENUS, "Tb has a MenuManger", null); //$NON-NLS-1$
+				// MenuManager m = (MenuManager) item;
+				// MMenuItem menu1 = addMenu(context, menu, m.getMenuText(),
+				// null,
+				// null, m.getId(), null);
+				// processMenuManager(context, menu1.getMenu(),
+				// m.getChildren());
+			} else if (item instanceof ActionContributionItem) {
+				ActionContributionItem aci = (ActionContributionItem) item;
+				if ((aci.getAction().getStyle() | IAction.AS_DROP_DOWN_MENU) == 0) {
+					ProcessItem.TOOLBAR.process(context, aci, tbModel);
+				} else {
+					// addToolRenderer(context, tbModel, item);
+				}
+			} else if (item instanceof CommandContributionItem) {
+				CommandContributionItem cci = (CommandContributionItem) item;
+				ProcessItem.TOOLBAR.process(context, cci, tbModel);
+			} else if (item instanceof Separator) {
+				// addSeparator(menu, item.getId());
+			} else if (item instanceof GroupMarker) {
+				// addSeparator(menu, item.getId());
+			} else {
+				Activator.trace(Policy.DEBUG_MENUS,
+						"unknown tool item: " + item.getClass().getName() //$NON-NLS-1$
+								+ " in " + context, null); //$NON-NLS-1$
+				// addToolRenderer(context, tbModel, item);
+			}
+		}
+	}
+
+	/**
+	 * @param imageDescriptor
+	 * @return
+	 */
+	public static String getImageUrl(ImageDescriptor imageDescriptor) {
+		if (imageDescriptor == null)
+			return null;
+		Class idc = imageDescriptor.getClass();
+		if (idc.getName().endsWith("URLImageDescriptor")) { //$NON-NLS-1$
+			URL url = getUrl(idc, imageDescriptor);
+			return url.toExternalForm();
+		}
+		return null;
+	}
+
+	private static URL getUrl(Class idc, ImageDescriptor imageDescriptor) {
+		try {
+			if (urlField == null) {
+				urlField = idc.getDeclaredField("url"); //$NON-NLS-1$
+				urlField.setAccessible(true);
+			}
+			return (URL) urlField.get(imageDescriptor);
+		} catch (SecurityException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (NoSuchFieldException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	private static MCommand getCommandById(IEclipseContext context, String cmdId) {
+		if (context == null)
+			return null;
+
+		MApplication app = (MApplication) context.get(MApplication.class
+				.getName());
+		final EList<MCommand> cmds = app.getCommands();
+		for (MCommand cmd : cmds) {
+			if (cmdId.equals(cmd.getId())) {
+				return cmd;
+			}
+		}
+		return null;
+	}
+
+	public static MMenuItem createMenuItem(IEclipseContext context,
+			String label, String imgPath, String id, String cmdId) {
+		MMenuItem newItem = MApplicationFactory.eINSTANCE.createMenuItem();
+		newItem.setId(id);
+		newItem.setName(label);
+		newItem.setIconURI(imgPath);
+		if (cmdId != null) {
+			MCommand mcmd = getCommandById(context, cmdId);
+			if (mcmd != null) {
+				// newItem.setCommand(mcmd);
+			} else {
+				//				System.err.println("No MCommand defined for " + cmdId); //$NON-NLS-1$
+			}
+		} else {
+			//			System.err.println("No command id for " + id); //$NON-NLS-1$
+		}
+		return newItem;
+	}
+
+	public static MToolItem createToolbarItem(IEclipseContext context,
+			String label, String imgPath, String id, String cmdId) {
+		MToolItem newItem = MApplicationFactory.eINSTANCE.createToolItem();
+		newItem.setId(id);
+		newItem.setTooltip(label);
+		newItem.setIconURI(imgPath);
+		Activator.trace(Policy.DEBUG_MENUS, "createToolbarItem: " + id //$NON-NLS-1$
+				+ ": " + label + ": " + cmdId, null); //$NON-NLS-1$//$NON-NLS-2$
+		if (cmdId != null) {
+			MCommand mcmd = getCommandById(context, cmdId);
+			if (mcmd != null) {
+				// newItem.setCommand(mcmd);
+			} else {
+				//				System.err.println("No MCommand defined for " + cmdId); //$NON-NLS-1$
+			}
+		} else {
+			//			System.err.println("No command id for " + id); //$NON-NLS-1$
+		}
+		return newItem;
+	}
+
+	private static MToolItem createTBItem(String ttip, String imgPath,
+			String id, String cmdId) {
+		MToolItem newItem = MApplicationFactory.eINSTANCE.createToolItem();
+		newItem.setId(id);
+		newItem.setTooltip(ttip);
+		newItem.setIconURI(imgPath);
+
+		return newItem;
+	}
+
+	public static MMenuItem addMenu(IEclipseContext context, MMenu parentMenu,
+			String label, String plugin, String imgPath, String id, String cmdId) {
+		// Sub-menus are implemented as an item with a menu... ??
+		MMenuItem newItem = createMenuItem(context, label, imgPath, id, cmdId);
+		parentMenu.getChildren().add(newItem);
+
+		return newItem;
+	}
+
+	public static MMenuItem addMenu(MMenuItem parentMenuItem, String label,
+			String plugin, String imgPath, String id, String cmdId) {
+		MMenu parentMenu = parentMenuItem;
+		return addMenu(null, parentMenu, label, plugin, imgPath, id, cmdId);
+	}
+
+	public static void addMenuItem(MMenuItem parentMenuItem, String label,
+			String plugin, String imgPath, String id, String cmdId) {
+		MMenuItem newItem = createMenuItem(null, label, imgPath, id, cmdId);
+		MMenu parentMenu = parentMenuItem;
+		parentMenu.getChildren().add(newItem);
+	}
+
+	public static void addToolbarItem(MToolBar tbModel, String label,
+			String plugin, String imgPath, String id, String cmdId) {
+		MToolItem newItem = createToolbarItem(null, label, imgPath, id, cmdId);
+		tbModel.getChildren().add(newItem);
+	}
+
+	public static void addMenuItem(IEclipseContext context, MMenu parentMenu,
+			String label, String plugin, String imgPath, String id, String cmdId) {
+		MMenuItem newItem = createMenuItem(context, label, imgPath, id, cmdId);
+		parentMenu.getChildren().add(newItem);
+	}
+
+	public static void addSeparator(MMenuItem parentMenuItem, String id) {
+		if (id != null)
+			return;
+		MMenuItem newItem = MApplicationFactory.eINSTANCE.createMenuItem();
+		newItem.setId(id);
+		newItem.setSeparator(true);
+		// newItem.setVisible(id == null);
+		parentMenuItem.getChildren().add(newItem);
+	}
+
+	public static void addSeparator(MMenu menu, String id, boolean visible) {
+		MMenuItem newItem = MApplicationFactory.eINSTANCE.createMenuItem();
+		if (id != null) {
+			newItem.setId(id);
+		}
+		newItem.setSeparator(true);
+		newItem.setVisible(visible);
+
+		menu.getChildren().add(newItem);
+	}
+
+	public static void loadToolbar(MToolBar tbModel) {
+		MToolItem tbItem = createTBItem("&New	Alt+Shift+N", null, //$NON-NLS-1$
+				"cmdId.New", "cmdId.New"); //$NON-NLS-1$//$NON-NLS-2$
+		tbModel.getChildren().add(tbItem);
+
+		tbItem = createTBItem(
+				"&Save", //$NON-NLS-1$
+				"platform:/plugin/org.eclipse.ui/icons/full/etool16/save_edit.gif", //$NON-NLS-1$
+				"cmdId.Save", "cmdId.Save"); //$NON-NLS-1$//$NON-NLS-2$
+		tbModel.getChildren().add(tbItem);
+
+		tbItem = createTBItem(
+				"&Print", //$NON-NLS-1$
+				"platform:/plugin/org.eclipse.ui/icons/full/etool16/print_edit.gif", //$NON-NLS-1$
+				"cmdId.Print", "cmdId.Print"); //$NON-NLS-1$//$NON-NLS-2$
+		tbModel.getChildren().add(tbItem);
+	}
+
+	static boolean getVisibleEnabled(IConfigurationElement element) {
+		IConfigurationElement[] children = element
+				.getChildren(IWorkbenchRegistryConstants.TAG_VISIBLE_WHEN);
+		String checkEnabled = null;
+
+		if (children.length > 0) {
+			checkEnabled = children[0]
+					.getAttribute(IWorkbenchRegistryConstants.ATT_CHECK_ENABLED);
+		}
+
+		return checkEnabled != null && checkEnabled.equalsIgnoreCase("true"); //$NON-NLS-1$
+	}
+
+	/*
+	 * Support Utilities
+	 */
+	public static String getId(IConfigurationElement element) {
+		String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+
+		// For sub-menu management -all- items must be id'd so enforce this
+		// here (we could optimize by checking the 'name' of the config
+		// element == "menu"
+		if (id == null || id.length() == 0) {
+			id = getCommandId(element);
+		}
+		if (id == null || id.length() == 0) {
+			id = element.toString();
+		}
+
+		return id;
+	}
+
+	public static boolean getRetarget(IConfigurationElement element) {
+		String r = element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_RETARGET);
+		return Boolean.valueOf(r);
+	}
+
+	public static String getName(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+	}
+
+	public static int getMode(IConfigurationElement element) {
+		if ("FORCE_TEXT".equals(element.getAttribute(IWorkbenchRegistryConstants.ATT_MODE))) { //$NON-NLS-1$
+			return CommandContributionItem.MODE_FORCE_TEXT;
+		}
+		return 0;
+	}
+
+	public static String getLabel(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL);
+	}
+
+	public static String getMnemonic(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_MNEMONIC);
+	}
+
+	public static String getTooltip(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_TOOLTIP);
+	}
+
+	public static String getIconPath(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
+	}
+
+	public static String getDisabledIconPath(IConfigurationElement element) {
+		return element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_DISABLEDICON);
+	}
+
+	public static String getHoverIconPath(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_HOVERICON);
+	}
+
+	public static ImageDescriptor getIconDescriptor(
+			IConfigurationElement element) {
+		String extendingPluginId = element.getDeclaringExtension()
+				.getContributor().getName();
+
+		String iconPath = getIconPath(element);
+		if (iconPath != null) {
+			return AbstractUIPlugin.imageDescriptorFromPlugin(
+					extendingPluginId, iconPath);
+		}
+		return null;
+	}
+
+	public static ImageDescriptor getDisabledIconDescriptor(
+			IConfigurationElement element) {
+		String extendingPluginId = element.getDeclaringExtension()
+				.getContributor().getName();
+
+		String iconPath = getDisabledIconPath(element);
+		if (iconPath != null) {
+			return AbstractUIPlugin.imageDescriptorFromPlugin(
+					extendingPluginId, iconPath);
+		}
+		return null;
+	}
+
+	public static ImageDescriptor getHoverIconDescriptor(
+			IConfigurationElement element) {
+		String extendingPluginId = element.getDeclaringExtension()
+				.getContributor().getName();
+
+		String iconPath = getHoverIconPath(element);
+		if (iconPath != null) {
+			return AbstractUIPlugin.imageDescriptorFromPlugin(
+					extendingPluginId, iconPath);
+		}
+		return null;
+	}
+
+	public static String getHelpContextId(IConfigurationElement element) {
+		return element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_HELP_CONTEXT_ID);
+	}
+
+	public static boolean isSeparatorVisible(IConfigurationElement element) {
+		String val = element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE);
+		return Boolean.valueOf(val).booleanValue();
+	}
+
+	public static String getClassSpec(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS);
+	}
+
+	public static String getCommandId(IConfigurationElement element) {
+		return element.getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID);
+	}
+
+	public static String getDefinitionId(IConfigurationElement element) {
+		return element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_DEFINITION_ID);
+	}
+
+	public static int getStyle(IConfigurationElement element) {
+		String style = element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_STYLE);
+		if (style == null || style.length() == 0) {
+			return CommandContributionItem.STYLE_PUSH;
+		}
+		if (IWorkbenchRegistryConstants.STYLE_TOGGLE.equals(style)) {
+			return CommandContributionItem.STYLE_CHECK;
+		}
+		if (IWorkbenchRegistryConstants.STYLE_RADIO.equals(style)) {
+			return CommandContributionItem.STYLE_RADIO;
+		}
+		if (IWorkbenchRegistryConstants.STYLE_PULLDOWN.equals(style)) {
+			return CommandContributionItem.STYLE_PULLDOWN;
+		}
+		return CommandContributionItem.STYLE_PUSH;
+	}
+
+	/**
+	 * @param element
+	 * @return A map of parameters names to parameter values. All Strings. The
+	 *         map may be empty.
+	 */
+	public static Map<String, String> getParameters(
+			IConfigurationElement element) {
+		HashMap<String, String> map = new HashMap<String, String>();
+		IConfigurationElement[] parameters = element
+				.getChildren(IWorkbenchRegistryConstants.TAG_PARAMETER);
+		for (int i = 0; i < parameters.length; i++) {
+			String name = parameters[i]
+					.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+			String value = parameters[i]
+					.getAttribute(IWorkbenchRegistryConstants.ATT_VALUE);
+			if (name != null && value != null) {
+				map.put(name, value);
+			}
+		}
+		return map;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyEvalContext.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyEvalContext.java
new file mode 100644
index 0000000..cd1d368
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyEvalContext.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui;
+
+import java.util.Collections;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+
+/**
+ *
+ */
+public class LegacyEvalContext implements IEvaluationContext {
+	public IEclipseContext eclipseContext = null;
+	private boolean allowActivation;
+
+	public LegacyEvalContext(IEclipseContext context) {
+		eclipseContext = context;
+	}
+
+	public void setAllowPluginActivation(boolean value) {
+		allowActivation = value;
+	}
+
+	public Object resolveVariable(String name, Object[] args)
+			throws CoreException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object removeVariable(String name) {
+		Object o = eclipseContext.get(name);
+		eclipseContext.remove(name);
+		return o;
+	}
+
+	public Object getVariable(String name) {
+		final Object obj = eclipseContext.get(name);
+		return obj == null ? IEvaluationContext.UNDEFINED_VARIABLE : obj;
+	}
+
+	public IEvaluationContext getRoot() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public IEvaluationContext getParent() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getDefaultVariable() {
+		final Object obj = eclipseContext
+				.get(ISources.ACTIVE_CURRENT_SELECTION_NAME);
+		return obj == null ? Collections.EMPTY_LIST : obj;
+	}
+
+	public boolean getAllowPluginActivation() {
+		return allowActivation;
+	}
+
+	public void addVariable(String name, Object value) {
+		eclipseContext.set(name, value);
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyHandlerService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyHandlerService.java
new file mode 100644
index 0000000..b1be89e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyHandlerService.java
@@ -0,0 +1,709 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.ui;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.ElementHandler;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.commands.EHandlerService;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MContext;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.handlers.IHandlerActivation;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.expressions.AndExpression;
+import org.eclipse.ui.internal.expressions.WorkbenchWindowExpression;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.services.SourcePriorityNameMapping;
+
+public class LegacyHandlerService implements IHandlerService {
+	private static final String PARM_MAP = "legacyParameterMap"; //$NON-NLS-1$
+	private static final String HANDLER_PREFIX = "HDL_"; //$NON-NLS-1$
+
+	public static class HandlerProxy {
+		IHandler handler = null;
+		Command command;
+		EHandlerActivation activation = null;
+
+		public HandlerProxy(Command command, IHandler handler) {
+			this.command = command;
+			this.handler = handler;
+		}
+
+		public boolean canExecute(IEclipseContext context) {
+			return handler.isEnabled();
+		}
+
+		public void execute(IEclipseContext context) {
+			Activator.trace(Policy.DEBUG_CMDS, "execute " + command + " and " //$NON-NLS-1$ //$NON-NLS-2$
+					+ handler + " with: " + context, null); //$NON-NLS-1$
+			LegacyEvalContext legacy = new LegacyEvalContext(context);
+			ExecutionEvent event = new ExecutionEvent(command, (Map) context
+					.get(PARM_MAP), null, legacy);
+			try {
+				handler.execute(event);
+			} catch (ExecutionException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+
+		public IHandler getHandler() {
+			return handler;
+		}
+	}
+
+	static class EHandlerActivation implements IHandlerActivation, Runnable {
+
+		IEclipseContext context;
+		private String commandId;
+		private IHandler handler;
+		HandlerProxy proxy;
+		Expression activeWhen;
+		boolean active;
+		int sourcePriority;
+		boolean participating = true;
+
+		/**
+		 * @param context
+		 * @param cmdId
+		 * @param handler
+		 * @param handlerProxy
+		 */
+		public EHandlerActivation(IEclipseContext context, String cmdId,
+				IHandler handler, HandlerProxy handlerProxy, Expression expr) {
+			this.context = context;
+			this.commandId = cmdId;
+			this.handler = handler;
+			this.proxy = handlerProxy;
+			this.activeWhen = expr;
+			this.sourcePriority = SourcePriorityNameMapping
+					.computeSourcePriority(activeWhen);
+			proxy.activation = this;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.handlers.IHandlerActivation#clearActive()
+		 */
+		public void clearActive() {
+			active = true;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.handlers.IHandlerActivation#getCommandId()
+		 */
+		public String getCommandId() {
+			return commandId;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.handlers.IHandlerActivation#getDepth()
+		 */
+		public int getDepth() {
+			// TODO Auto-generated method stub
+			return 0;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.handlers.IHandlerActivation#getHandler()
+		 */
+		public IHandler getHandler() {
+			return handler;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.ui.handlers.IHandlerActivation#getHandlerService()
+		 */
+		public IHandlerService getHandlerService() {
+			return (IHandlerService) context.get(IHandlerService.class
+					.getName());
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.ui.handlers.IHandlerActivation#isActive(org.eclipse.core
+		 * .expressions.IEvaluationContext)
+		 */
+		public boolean isActive(IEvaluationContext context) {
+			return active;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.ui.internal.services.IEvaluationResultCache#clearResult()
+		 */
+		public void clearResult() {
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.ui.internal.services.IEvaluationResultCache#evaluate(
+		 * org.eclipse.core.expressions.IEvaluationContext)
+		 */
+		public boolean evaluate(IEvaluationContext context) {
+			if (activeWhen == null) {
+				active = true;
+			} else {
+				try {
+					active = activeWhen.evaluate(context) != EvaluationResult.FALSE;
+				} catch (CoreException e) {
+					Activator.trace(Policy.DEBUG_CMDS,
+							"Failed to calculate active", e); //$NON-NLS-1$
+				}
+			}
+			return active;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.ui.internal.services.IEvaluationResultCache#getExpression
+		 * ()
+		 */
+		public Expression getExpression() {
+			return activeWhen;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.ui.internal.services.IEvaluationResultCache#getSourcePriority
+		 * ()
+		 */
+		public int getSourcePriority() {
+			return sourcePriority;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.ui.internal.services.IEvaluationResultCache#setResult
+		 * (boolean)
+		 */
+		public void setResult(boolean result) {
+			// TODO Auto-generated method stub
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Comparable#compareTo(java.lang.Object)
+		 */
+		public int compareTo(Object o) {
+			EHandlerActivation activation = (EHandlerActivation) o;
+			int difference;
+
+			// Check the priorities
+			int thisPriority = this.getSourcePriority();
+			int thatPriority = activation.getSourcePriority();
+
+			// rogue bit problem - ISources.ACTIVE_MENU
+			int thisLsb = 0;
+			int thatLsb = 0;
+
+			if (((thisPriority & ISources.ACTIVE_MENU) | (thatPriority & ISources.ACTIVE_MENU)) != 0) {
+				thisLsb = thisPriority & 1;
+				thisPriority = (thisPriority >> 1) & 0x7fffffff;
+				thatLsb = thatPriority & 1;
+				thatPriority = (thatPriority >> 1) & 0x7fffffff;
+			}
+
+			difference = thisPriority - thatPriority;
+			if (difference != 0) {
+				return difference;
+			}
+
+			// if all of the higher bits are the same, check the
+			// difference of the LSB
+			difference = thisLsb - thatLsb;
+			if (difference != 0) {
+				return difference;
+			}
+
+			// Check depth
+			final int thisDepth = this.getDepth();
+			final int thatDepth = activation.getDepth();
+			difference = thisDepth - thatDepth;
+			return difference;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Object#toString()
+		 */
+		@Override
+		public String toString() {
+			return "EHA: " + active + ":" + sourcePriority + ":" + commandId + ": " + proxy //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+					+ ": " + handler + ": " + context; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Runnable#run()
+		 */
+		public void run() {
+			if (!participating) {
+				return;
+			}
+			final EHandlerService hs = (EHandlerService) context
+					.get(EHandlerService.class.getName());
+			Object obj = context.get(HANDLER_PREFIX + commandId);
+
+			if (evaluate(new LegacyEvalContext(context))) {
+				if (obj instanceof HandlerProxy) {
+					final EHandlerActivation bestActivation = ((HandlerProxy) obj).activation;
+					final int comparison = bestActivation.compareTo(this);
+					if (comparison < 0) {
+						hs.activateHandler(commandId, proxy);
+					}
+				} else if (obj == null) {
+					hs.activateHandler(commandId, proxy);
+				}
+			} else {
+				if (obj == proxy) {
+					hs.deactivateHandler(commandId, proxy);
+				}
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.application.IActionBarConfigurer#registerGlobalAction(
+	 * org.eclipse.jface.action.IAction)
+	 */
+	public static IHandlerActivation registerLegacyHandler(
+			final IEclipseContext context, String id, final String cmdId,
+			IHandler handler, Expression activeWhen) {
+
+		ECommandService cs = (ECommandService) context
+				.get(ECommandService.class.getName());
+		Command command = cs.getCommand(cmdId);
+		HandlerProxy handlerProxy = new HandlerProxy(command, handler);
+		final EHandlerActivation activation = new EHandlerActivation(context,
+				cmdId, handler, handlerProxy, activeWhen);
+		context.runAndTrack(activation);
+		return activation;
+	}
+
+	private IEclipseContext eclipseContext;
+	private IEvaluationContext evalContext;
+	private Expression defaultExpression = null;
+
+	public LegacyHandlerService(IEclipseContext context) {
+		eclipseContext = context;
+		evalContext = new LegacyEvalContext(eclipseContext);
+		IWorkbenchWindow window = (IWorkbenchWindow) eclipseContext
+				.get(IWorkbenchWindow.class.getName());
+		if (window != null) {
+			defaultExpression = new WorkbenchWindowExpression(window);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#activateHandler(org.eclipse.ui
+	 * .handlers.IHandlerActivation)
+	 */
+	public IHandlerActivation activateHandler(IHandlerActivation activation) {
+		EHandlerActivation eActivation = (EHandlerActivation) activation;
+		eActivation.participating = true;
+		eActivation.context.runAndTrack(eActivation);
+		return activation;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+	 * org.eclipse.core.commands.IHandler)
+	 */
+	public IHandlerActivation activateHandler(String commandId, IHandler handler) {
+		return registerLegacyHandler(eclipseContext, commandId, commandId,
+				handler, defaultExpression);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+	 * org.eclipse.core.commands.IHandler,
+	 * org.eclipse.core.expressions.Expression)
+	 */
+	public IHandlerActivation activateHandler(String commandId,
+			IHandler handler, Expression expression) {
+		return activateHandler(commandId, handler, expression, false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+	 * org.eclipse.core.commands.IHandler,
+	 * org.eclipse.core.expressions.Expression, boolean)
+	 */
+	public IHandlerActivation activateHandler(String commandId,
+			IHandler handler, Expression expression, boolean global) {
+		if (global || defaultExpression == null) {
+			return registerLegacyHandler(eclipseContext, commandId, commandId,
+					handler, expression);
+		}
+		AndExpression andExpr = new AndExpression();
+		andExpr.add(expression);
+		andExpr.add(defaultExpression);
+		return registerLegacyHandler(eclipseContext, commandId, commandId,
+				handler, andExpr);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+	 * org.eclipse.core.commands.IHandler,
+	 * org.eclipse.core.expressions.Expression, int)
+	 */
+	public IHandlerActivation activateHandler(String commandId,
+			IHandler handler, Expression expression, int sourcePriorities) {
+		return activateHandler(commandId, handler, expression, false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#createContextSnapshot(boolean)
+	 */
+	public IEvaluationContext createContextSnapshot(boolean includeSelection) {
+		return new LegacyEvalContext(EclipseContextFactory.create(
+				getFocusContext(PlatformUI.getWorkbench().getDisplay()),
+				UISchedulerStrategy.getInstance()));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#createExecutionEvent(org.eclipse
+	 * .core.commands.Command, org.eclipse.swt.widgets.Event)
+	 */
+	public ExecutionEvent createExecutionEvent(Command command, Event event) {
+		LegacyEvalContext legacy = new LegacyEvalContext(
+				getFocusContext(PlatformUI.getWorkbench().getDisplay()));
+		ExecutionEvent e = new ExecutionEvent(command, Collections.EMPTY_MAP,
+				event, legacy);
+		return e;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#createExecutionEvent(org.eclipse
+	 * .core.commands.ParameterizedCommand, org.eclipse.swt.widgets.Event)
+	 */
+	public ExecutionEvent createExecutionEvent(ParameterizedCommand command,
+			Event event) {
+		LegacyEvalContext legacy = new LegacyEvalContext(
+				getFocusContext(PlatformUI.getWorkbench().getDisplay()));
+		ExecutionEvent e = new ExecutionEvent(command.getCommand(), command
+				.getParameterMap(), event, legacy);
+		return e;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#deactivateHandler(org.eclipse
+	 * .ui.handlers.IHandlerActivation)
+	 */
+	public void deactivateHandler(IHandlerActivation activation) {
+		EHandlerActivation eActivation = (EHandlerActivation) activation;
+		eActivation.participating = false;
+		EHandlerService hs = (EHandlerService) eActivation.context
+				.get(EHandlerService.class.getName());
+		hs.deactivateHandler(eActivation.getCommandId(), eActivation.proxy);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#deactivateHandlers(java.util.
+	 * Collection)
+	 */
+	public void deactivateHandlers(Collection activations) {
+		Object[] array = activations.toArray();
+		for (int i = 0; i < array.length; i++) {
+			deactivateHandler((IHandlerActivation) array[i]);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#executeCommand(java.lang.String,
+	 * org.eclipse.swt.widgets.Event)
+	 */
+	public Object executeCommand(String commandId, Event event)
+			throws ExecutionException, NotDefinedException,
+			NotEnabledException, NotHandledException {
+		ECommandService cs = (ECommandService) getFocusContext(
+				PlatformUI.getWorkbench().getDisplay()).get(
+				ECommandService.class.getName());
+		final Command command = cs.getCommand(commandId);
+		return executeCommand(ParameterizedCommand.generateCommand(command,
+				null), event);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#executeCommand(org.eclipse.core
+	 * .commands.ParameterizedCommand, org.eclipse.swt.widgets.Event)
+	 */
+	public Object executeCommand(ParameterizedCommand command, Event event)
+			throws ExecutionException, NotDefinedException,
+			NotEnabledException, NotHandledException {
+		EHandlerService hs = (EHandlerService) getFocusContext(
+				PlatformUI.getWorkbench().getDisplay()).get(
+				EHandlerService.class.getName());
+		hs.getContext().set(PARM_MAP, command.getParameterMap());
+		return hs.executeHandler(command);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#executeCommandInContext(org.eclipse
+	 * .core.commands.ParameterizedCommand, org.eclipse.swt.widgets.Event,
+	 * org.eclipse.core.expressions.IEvaluationContext)
+	 */
+	public Object executeCommandInContext(ParameterizedCommand command,
+			Event event, IEvaluationContext context) throws ExecutionException,
+			NotDefinedException, NotEnabledException, NotHandledException {
+		if (context instanceof LegacyEvalContext) {
+			EHandlerService hs = (EHandlerService) ((LegacyEvalContext) context).eclipseContext
+					.get(EHandlerService.class.getName());
+			return hs.executeHandler(command);
+		}
+		return executeCommand(command, event);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.handlers.IHandlerService#getCurrentState()
+	 */
+	public IEvaluationContext getCurrentState() {
+		return evalContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.handlers.IHandlerService#readRegistry()
+	 */
+	public void readRegistry() {
+		readDefaultHandlers();
+		readHandlers();
+	}
+
+	private void readHandlers() {
+		IConfigurationElement[] elements = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_HANDLERS);
+		for (IConfigurationElement configElement : elements) {
+			String commandId = configElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID);
+			if (commandId == null || commandId.length() == 0) {
+				continue;
+			}
+			String defaultHandler = configElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS);
+			if ((defaultHandler == null)
+					&& (configElement
+							.getChildren(IWorkbenchRegistryConstants.TAG_CLASS).length == 0)) {
+				continue;
+			}
+			Expression activeWhen = null;
+			final IConfigurationElement[] awChildren = configElement
+					.getChildren(IWorkbenchRegistryConstants.TAG_ACTIVE_WHEN);
+			if (awChildren.length > 0) {
+				final IConfigurationElement[] subChildren = awChildren[0]
+						.getChildren();
+				if (subChildren.length != 1) {
+					Activator.trace(Policy.DEBUG_CMDS,
+							"Incorrect activeWhen element " + commandId, null); //$NON-NLS-1$
+					continue;
+				}
+				final ElementHandler elementHandler = ElementHandler
+						.getDefault();
+				final ExpressionConverter converter = ExpressionConverter
+						.getDefault();
+				try {
+					activeWhen = elementHandler.create(converter,
+							subChildren[0]);
+				} catch (CoreException e) {
+					Activator.trace(Policy.DEBUG_CMDS,
+							"Incorrect activeWhen element " + commandId, e); //$NON-NLS-1$
+				}
+			}
+			registerLegacyHandler(eclipseContext, commandId, commandId,
+					new org.eclipse.ui.internal.handlers.HandlerProxy(
+							commandId, configElement,
+							IWorkbenchRegistryConstants.ATT_CLASS), activeWhen);
+		}
+	}
+
+	private void readDefaultHandlers() {
+		IConfigurationElement[] elements = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_COMMANDS);
+		for (IConfigurationElement configElement : elements) {
+			String id = configElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+			if (id == null || id.length() == 0) {
+				continue;
+			}
+			String defaultHandler = configElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_DEFAULT_HANDLER);
+			if ((defaultHandler == null)
+					&& (configElement
+							.getChildren(IWorkbenchRegistryConstants.TAG_DEFAULT_HANDLER).length == 0)) {
+				continue;
+			}
+			registerLegacyHandler(eclipseContext, id, id,
+					new org.eclipse.ui.internal.handlers.HandlerProxy(id,
+							configElement,
+							IWorkbenchRegistryConstants.ATT_DEFAULT_HANDLER),
+					null);
+
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.handlers.IHandlerService#setHelpContextId(org.eclipse.
+	 * core.commands.IHandler, java.lang.String)
+	 */
+	public void setHelpContextId(IHandler handler, String helpContextId) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.services.IServiceWithSources#addSourceProvider(org.eclipse
+	 * .ui.ISourceProvider)
+	 */
+	public void addSourceProvider(ISourceProvider provider) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.services.IServiceWithSources#removeSourceProvider(org.
+	 * eclipse.ui.ISourceProvider)
+	 */
+	public void removeSourceProvider(ISourceProvider provider) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.services.IDisposable#dispose()
+	 */
+	public void dispose() {
+		// TODO Auto-generated method stub
+
+	}
+
+	private IEclipseContext getFocusContext(Display display) {
+		// find the first useful part in the model
+		Control control = display.getFocusControl();
+		Object modelObj = null;
+		while (control != null) {
+			modelObj = control.getData(AbstractPartRenderer.OWNING_ME);
+			if (modelObj instanceof MContext)
+				return ((MContext) modelObj).getContext();
+			control = control.getParent();
+		}
+		return eclipseContext;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/actions/ContributedAction.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/actions/ContributedAction.java
new file mode 100644
index 0000000..da33322
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/actions/ContributedAction.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.actions;
+
+import java.util.Collections;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandler2;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.actions.CommandAction;
+import org.eclipse.ui.internal.handlers.ActionDelegateHandlerProxy;
+import org.eclipse.ui.internal.handlers.HandlerService;
+import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.part.MultiPageEditorSite;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * For a declarative editor action, see if we can link it to a command.
+ * <p>
+ * This is a legacy bridge class, and should not be used outside of the Eclipse
+ * SDK. Please use menu contributions to display a command in a menu or toolbar.
+ * </p>
+ * <p>
+ * <b>Note:</b> Clients may instantiate.
+ * </p>
+ * 
+ * @since 3.3
+ */
+public final class ContributedAction extends CommandAction {
+	private IEvaluationContext appContext;
+
+	private IHandler partHandler;
+
+	private boolean localHandler = false;
+
+	private IPartListener partListener;
+
+	/**
+	 * Create an action that can call a command.
+	 * 
+	 * @param locator
+	 *            The appropriate service locator to use. If you use a part site
+	 *            as your locator, this action will be tied to your part.
+	 * @param element
+	 *            the contributed action element
+	 */
+	public ContributedAction(IServiceLocator locator,
+			IConfigurationElement element) throws CommandNotMappedException {
+
+		String actionId = element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+		String commandId = element
+				.getAttribute(IWorkbenchRegistryConstants.ATT_DEFINITION_ID);
+
+		// TODO throw some more exceptions here :-)
+
+		String contributionId = null;
+		if (commandId == null) {
+
+			Object obj = element.getParent();
+			if (obj instanceof IConfigurationElement) {
+				contributionId = ((IConfigurationElement) obj)
+						.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+				if (contributionId == null) {
+					throw new CommandNotMappedException("Action " //$NON-NLS-1$
+							+ actionId + " configuration element invalid"); //$NON-NLS-1$
+				}
+			}
+			// legacy bridge part
+			IActionCommandMappingService mapping = (IActionCommandMappingService) locator
+					.getService(IActionCommandMappingService.class);
+			if (mapping == null) {
+				throw new CommandNotMappedException(
+						"No action mapping service available"); //$NON-NLS-1$
+			}
+
+			commandId = mapping.getCommandId(mapping.getGeneratedCommandId(
+					contributionId, actionId));
+		}
+		// what, still no command?
+		if (commandId == null) {
+			throw new CommandNotMappedException("Action " + actionId //$NON-NLS-1$
+					+ " in contribution " + contributionId //$NON-NLS-1$
+					+ " not mapped to a command"); //$NON-NLS-1$
+		}
+
+		init(locator, commandId, null);
+
+		if (locator instanceof IWorkbenchPartSite) {
+			updateSiteAssociations((IWorkbenchPartSite) locator, commandId,
+					actionId, element);
+		}
+
+		setId(actionId);
+	}
+
+	private void updateSiteAssociations(IWorkbenchPartSite site,
+			String commandId, String actionId, IConfigurationElement element) {
+		IWorkbenchLocationService wls = (IWorkbenchLocationService) site
+				.getService(IWorkbenchLocationService.class);
+		IWorkbench workbench = wls.getWorkbench();
+		IWorkbenchWindow window = wls.getWorkbenchWindow();
+		IHandlerService serv = (IHandlerService) workbench
+				.getService(IHandlerService.class);
+		appContext = new EvaluationContext(serv.getCurrentState(),
+				Collections.EMPTY_LIST);
+
+		// set up the appContext as we would want it.
+		appContext.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME,
+				StructuredSelection.EMPTY);
+		appContext.addVariable(ISources.ACTIVE_PART_NAME, site.getPart());
+		appContext.addVariable(ISources.ACTIVE_PART_ID_NAME, site.getId());
+		appContext.addVariable(ISources.ACTIVE_SITE_NAME, site);
+		if (site instanceof IEditorSite) {
+			appContext.addVariable(ISources.ACTIVE_EDITOR_NAME, site.getPart());
+			appContext
+					.addVariable(ISources.ACTIVE_EDITOR_ID_NAME, site.getId());
+		}
+		appContext.addVariable(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, window);
+		appContext.addVariable(ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
+				window.getShell());
+
+		// E4MOD --- modified for E4 due to the downcast to HandlerService:
+		if (serv instanceof HandlerService) {
+			// 3.x processing: notice downcast to HandlerService
+			HandlerService realService = (HandlerService) serv;
+			partHandler = realService.findHandler(commandId, appContext);
+		} else if (site instanceof PartSite) { // E4 processing
+			IEclipseContext context = ((PartSite) site).getContext();
+			Object handler = context.get(commandId, new Object[] { "handler" }); //$NON-NLS-1$
+			if (handler instanceof IHandler)
+				partHandler = (IHandler) handler;
+			else if (handler instanceof LegacyHandlerService.HandlerProxy)
+				partHandler = ((LegacyHandlerService.HandlerProxy) handler)
+						.getHandler();
+		}
+		// E4MOD --- end of modified part
+		if (partHandler == null) {
+			localHandler = true;
+			// if we can't find the handler, then at least we can
+			// call the action delegate run method
+			partHandler = new ActionDelegateHandlerProxy(element,
+					IWorkbenchRegistryConstants.ATT_CLASS, actionId,
+					getParameterizedCommand(), site.getWorkbenchWindow(), null,
+					null, null);
+		}
+		if (site instanceof MultiPageEditorSite) {
+			IHandlerService siteServ = (IHandlerService) site
+					.getService(IHandlerService.class);
+			siteServ.activateHandler(commandId, partHandler);
+		}
+
+		if (getParameterizedCommand() != null) {
+			getParameterizedCommand().getCommand().removeCommandListener(
+					getCommandListener());
+		}
+		site.getPage().addPartListener(getPartListener());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.internal.actions.CommandAction#runWithEvent(org.eclipse
+	 * .swt.widgets.Event)
+	 */
+	public void runWithEvent(Event event) {
+		if (partHandler != null && getParameterizedCommand() != null) {
+			IHandler oldHandler = getParameterizedCommand().getCommand()
+					.getHandler();
+			try {
+				getParameterizedCommand().getCommand().setHandler(partHandler);
+				getParameterizedCommand().executeWithChecks(event, appContext);
+			} catch (ExecutionException e) {
+				// TODO some logging, perhaps?
+			} catch (NotDefinedException e) {
+				// TODO some logging, perhaps?
+			} catch (NotEnabledException e) {
+				// TODO some logging, perhaps?
+			} catch (NotHandledException e) {
+				// TODO some logging, perhaps?
+			} finally {
+				getParameterizedCommand().getCommand().setHandler(oldHandler);
+			}
+		} else {
+			super.runWithEvent(event);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.action.Action#isEnabled()
+	 */
+	public boolean isEnabled() {
+		if (partHandler != null) {
+			if (partHandler instanceof IHandler2) {
+				((IHandler2) partHandler).setEnabled(appContext);
+			}
+			return partHandler.isEnabled();
+		}
+		return false;
+	}
+
+	private IPartListener getPartListener() {
+		if (partListener == null) {
+			final IWorkbenchPartSite site = (IWorkbenchPartSite) appContext
+					.getVariable(ISources.ACTIVE_SITE_NAME);
+
+			final IWorkbenchPart currentPart;
+			if (site instanceof MultiPageEditorSite) {
+				currentPart = ((MultiPageEditorSite) site).getMultiPageEditor();
+			} else {
+				currentPart = site.getPart();
+			}
+
+			partListener = new IPartListener() {
+				public void partActivated(IWorkbenchPart part) {
+				}
+
+				public void partBroughtToTop(IWorkbenchPart part) {
+				}
+
+				public void partClosed(IWorkbenchPart part) {
+					if (part == currentPart) {
+						ContributedAction.this.disposeAction();
+					}
+				}
+
+				public void partDeactivated(IWorkbenchPart part) {
+				}
+
+				public void partOpened(IWorkbenchPart part) {
+				}
+			};
+		}
+		return partListener;
+	}
+
+	// TODO make public in 3.4
+	private void disposeAction() {
+		if (appContext != null) {
+			if (localHandler) {
+				partHandler.dispose();
+			}
+			if (partListener != null) {
+				IWorkbenchPartSite site = (IWorkbenchPartSite) appContext
+						.getVariable(ISources.ACTIVE_SITE_NAME);
+				site.getPage().removePartListener(partListener);
+				partListener = null;
+			}
+			appContext = null;
+			partHandler = null;
+		}
+		dispose();
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java
new file mode 100644
index 0000000..79a10dd
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.ui.IActionBars2;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.SubActionBars2;
+import org.eclipse.ui.dnd.IDragAndDropService;
+
+/**
+ * An editor container manages the services for an editor.
+ */
+public class EditorSite extends PartSite implements IEditorSite {
+	/* package */// static final int PROP_REUSE_EDITOR = -0x101;
+
+	// private ListenerList propChangeListeners = new ListenerList(1);
+
+	private SubActionBars ab = null;
+
+	/**
+	 * Constructs an EditorSite for an editor.
+	 */
+	public EditorSite(IEditorReference ref, IEditorPart editor,
+			WorkbenchPage page) {
+		super(ref, editor, page);
+
+		// Initialize the services specific to this editor site.
+		initializeDefaultServices();
+	}
+
+	/**
+	 * Initialize the local services.
+	 */
+	private void initializeDefaultServices() {
+		// Register an implementation of the service appropriate for the
+		// EditorSite.
+		final IDragAndDropService editorDTService = new EditorSiteDragAndDropServiceImpl();
+		serviceLocator.registerService(IDragAndDropService.class,
+				editorDTService);
+	}
+
+	public void setActionBars(SubActionBars bars) {
+		super.setActionBars(bars);
+
+		if (bars instanceof IActionBars2) {
+			ab = new SubActionBars2((IActionBars2) bars, this);
+		} else {
+			ab = new SubActionBars(bars, this);
+		}
+	}
+
+	public void activateActionBars(boolean forceVisibility) {
+		if (ab != null) {
+			ab.activate(forceVisibility);
+		}
+		super.activateActionBars(forceVisibility);
+	}
+
+	public void deactivateActionBars(boolean forceHide) {
+		if (ab != null) {
+			ab.deactivate(forceHide);
+		}
+		super.deactivateActionBars(forceHide);
+	}
+
+	/**
+	 * Returns the editor action bar contributor for this editor.
+	 * <p>
+	 * An action contributor is responsable for the creation of actions. By
+	 * design, this contributor is used for one or more editors of the same
+	 * type. Thus, the contributor returned by this method is not owned
+	 * completely by the editor. It is shared.
+	 * </p>
+	 * 
+	 * @return the editor action bar contributor
+	 */
+	public IEditorActionBarContributor getActionBarContributor() {
+		EditorActionBars bars = (EditorActionBars) getActionBars();
+		if (bars != null) {
+			return bars.getEditorContributor();
+		}
+
+		return null;
+	}
+
+	/**
+	 * Returns the extension editor action bar contributor for this editor.
+	 */
+	public IEditorActionBarContributor getExtensionActionBarContributor() {
+		EditorActionBars bars = (EditorActionBars) getActionBars();
+		if (bars != null) {
+			return bars.getExtensionContributor();
+		}
+
+		return null;
+	}
+
+	/**
+	 * Returns the editor
+	 */
+	public IEditorPart getEditorPart() {
+		return (IEditorPart) getPart();
+	}
+
+	protected String getInitialScopeId() {
+		return "org.eclipse.ui.textEditorScope"; //$NON-NLS-1$
+	}
+
+	public void dispose() {
+		super.dispose();
+
+		if (ab != null) {
+			ab.dispose();
+		}
+	}
+
+	public final void registerContextMenu(final MenuManager menuManager,
+			final ISelectionProvider selectionProvider,
+			final boolean includeEditorInput) {
+		registerContextMenu(getId(), menuManager, selectionProvider,
+				includeEditorInput);
+	}
+
+	public final void registerContextMenu(final String menuId,
+			final MenuManager menuManager,
+			final ISelectionProvider selectionProvider,
+			final boolean includeEditorInput) {
+		if (menuExtenders == null) {
+			menuExtenders = new ArrayList(1);
+		}
+
+		PartSite.registerContextMenu(menuId, menuManager, selectionProvider,
+				includeEditorInput, getPart(), menuExtenders);
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ModelExtensionProcessor.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ModelExtensionProcessor.java
new file mode 100644
index 0000000..52bfc33
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ModelExtensionProcessor.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import java.util.ArrayList;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IContributor;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.RegistryFactory;
+import org.eclipse.e4.core.services.Logger;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+
+// TBD this should be incorporated into both E4 and legacy processing
+
+/**
+ * Process extensions to E4 model contributed via extensions.
+ */
+public class ModelExtensionProcessor {
+
+	final private static String extensionPointID = "org.eclipse.e4.workbench.model"; //$NON-NLS-1$
+
+	/**
+	 * Preferred default parent ID, if none specified
+	 */
+	final private static String preferredID1 = "Horizontal Sash[right]"; //$NON-NLS-1$
+
+	/**
+	 * Alternative preferred default parent ID, if none specified
+	 */
+	final private static String preferredID2 = "bottom"; //$NON-NLS-1$
+
+	/**
+	 * Model extensions as described by the extension registry
+	 */
+	private class ModelExtension {
+		private String uri;
+		private String parentID;
+		private IContributor contributor;
+
+		public ModelExtension(String uri, String parentID,
+				IContributor contributor) {
+			super();
+			this.uri = uri;
+			this.parentID = parentID;
+			this.contributor = contributor;
+		}
+
+		public URI getURI() {
+			if (uri == null)
+				return null;
+			String bundleName = contributor.getName();
+			String path = bundleName + '/' + uri;
+			try {
+				return URI.createPlatformPluginURI(path, false);
+			} catch (RuntimeException e) {
+				log("Model extension has invalid location", e); //$NON-NLS-1$
+				return null;
+			}
+		}
+
+		public String getParentID() {
+			return parentID;
+		}
+
+	}
+
+	private MWindow e4Window;
+
+	/**
+	 * Constructs processor for the model extensions on the MWindow
+	 * 
+	 * @param e4Window
+	 */
+	public ModelExtensionProcessor(MWindow e4Window) {
+		this.e4Window = e4Window;
+	}
+
+	/**
+	 * Add extensions to the specified window.
+	 */
+	public void addModelExtensions() {
+		ModelExtension[] extensions = readExtensionRegistry();
+		for (ModelExtension extension : extensions) {
+			URI uri = extension.getURI();
+			if (uri == null) {
+				log("Unable to find location for the model extension \"{0}\"", //$NON-NLS-1$
+						extension.contributor.getName());
+				continue;
+			}
+			Resource resource;
+			try {
+				resource = new ResourceSetImpl().getResource(uri, true);
+			} catch (RuntimeException e) {
+				log("Unable to read model extension", e); //$NON-NLS-1$
+				continue;
+			}
+			EList contents = resource.getContents();
+			if (contents.isEmpty())
+				continue;
+			Object extensionRoot = contents.get(0);
+			if (!(extensionRoot instanceof MUIElement)) {
+				log("Unable to create model extension \"{0}\"", //$NON-NLS-1$
+						extension.contributor.getName());
+				continue;
+			}
+
+			MUIElement root = (MUIElement) extensionRoot;
+			MElementContainer<MUIElement> parentElement = null;
+			if (root instanceof MWindow)
+				parentElement = (MElementContainer<MUIElement>) ((MUIElement) e4Window);
+			else
+				parentElement = findDefaultParent(extension.getParentID());
+			if (parentElement != null)
+				parentElement.getChildren().add(root);
+		}
+	}
+
+	private MElementContainer<MUIElement> findDefaultParent(String parentID) {
+		MUIElement defaultElement = null;
+		// Try the specified ID
+		if (parentID != null) {
+			defaultElement = ModeledPageLayout.findElementById(e4Window,
+					parentID);
+			if (defaultElement != null)
+				return (MElementContainer<MUIElement>) defaultElement;
+		}
+
+		// Try first preferred ID
+		defaultElement = ModeledPageLayout.findElementById(e4Window,
+				preferredID1);
+		if (defaultElement != null)
+			return (MElementContainer<MUIElement>) defaultElement;
+
+		// Try second preferred ID - parent of "bottom"
+		defaultElement = ModeledPageLayout.findPart(e4Window, preferredID2);
+		if (defaultElement != null)
+			return defaultElement.getParent();
+
+		return null;
+	}
+
+	private ModelExtension[] readExtensionRegistry() {
+		IExtensionRegistry registry = RegistryFactory.getRegistry();
+		IExtensionPoint extPoint = registry.getExtensionPoint(extensionPointID);
+		IExtension[] extensions = extPoint.getExtensions();
+		ArrayList<ModelExtension> result = new ArrayList();
+		for (IExtension extension : extensions) {
+			IConfigurationElement[] ces = extension.getConfigurationElements();
+			for (IConfigurationElement ce : ces) {
+				if (!"model".equals(ce.getName())) //$NON-NLS-1$
+					continue;
+				String attrURI = ce.getAttribute("location"); //$NON-NLS-1$
+				String attrParent = ce.getAttribute("parentID"); //$NON-NLS-1$
+				IContributor contributor = ce.getContributor();
+				ModelExtension modelExt = new ModelExtension(attrURI,
+						attrParent, contributor);
+				result.add(modelExt);
+			}
+		}
+		ModelExtension[] typedResult = new ModelExtension[result.size()];
+		result.toArray(typedResult);
+		return typedResult;
+	}
+
+	private void log(String msg, Exception e) {
+		IEclipseContext context = e4Window.getContext();
+		Logger logger = (Logger) context.get(Logger.class.getName());
+		if (logger == null)
+			e.printStackTrace();
+		else
+			logger.error(e, msg);
+	}
+
+	private void log(String msg, String arg) {
+		IEclipseContext context = e4Window.getContext();
+		Logger logger = (Logger) context.get(Logger.class.getName());
+		if (logger == null)
+			System.err.println(msg);
+		else
+			logger.error(msg, arg);
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartService.java
new file mode 100644
index 0000000..138177a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartService.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import java.util.ArrayList;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+
+public class PartService implements IPartService {
+	private static Point ZERO = new Point(0, 0);
+
+	private PartListenerList listeners = new PartListenerList();
+
+	private PartListenerList2 listeners2 = new PartListenerList2();
+	private IWorkbenchPartReference activePart = null;
+
+	private String debugListenersKey;
+	private String debugListeners2Key;
+
+	private ArrayList activeControlJobs = new ArrayList();
+
+	public PartService(String debugListenersKey, String debugListeners2Key) {
+		this.debugListeners2Key = debugListeners2Key;
+		this.debugListenersKey = debugListenersKey;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPartService
+	 */
+	public void addPartListener(IPartListener l) {
+		listeners.addPartListener(l);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPartService
+	 */
+	public void addPartListener(IPartListener2 l) {
+		listeners2.addPartListener(l);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPartService
+	 */
+	public void removePartListener(IPartListener l) {
+		listeners.removePartListener(l);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPartService
+	 */
+	public void removePartListener(IPartListener2 l) {
+		listeners2.removePartListener(l);
+	}
+
+	private abstract class PartJob {
+		IWorkbenchPartReference ref;
+		Control control;
+
+		public PartJob(IWorkbenchPartReference ref, Control c) {
+			this.ref = ref;
+			this.control = c;
+		}
+
+		abstract void fire();
+	}
+
+	private class PartListener implements Listener {
+		public void handleEvent(Event event) {
+			processPartJobs();
+		}
+	}
+
+	private PartListener partListener = new PartListener();
+
+	private class PartActivated extends PartJob {
+		public PartActivated(IWorkbenchPartReference ref, Control c) {
+			super(ref, c);
+		}
+
+		void fire() {
+			firePartActivated(ref);
+		}
+	}
+
+	private class PartVisible extends PartJob {
+		public PartVisible(IWorkbenchPartReference ref, Control c) {
+			super(ref, c);
+		}
+
+		void fire() {
+			firePartVisible(ref);
+		}
+	}
+
+	private class PartTop extends PartJob {
+		public PartTop(IWorkbenchPartReference ref, Control c) {
+			super(ref, c);
+		}
+
+		void fire() {
+			firePartBroughtToTop(ref);
+		}
+	}
+
+	private Control deferControl(IWorkbenchPartReference ref) {
+		return null;
+	}
+
+	private void addControlListener(Control control, PartJob listener) {
+		control.addListener(SWT.Resize, partListener);
+		control.addListener(SWT.Activate, partListener);
+		control.addListener(SWT.Dispose, partListener);
+		activeControlJobs.add(listener);
+	}
+
+	void processPartJobs() {
+		if (activeControlJobs.isEmpty()) {
+			return;
+		}
+
+		ArrayList toRemove = new ArrayList();
+		PartJob[] jobs = (PartJob[]) activeControlJobs
+				.toArray(new PartJob[activeControlJobs.size()]);
+		for (int i = 0; i < jobs.length; i++) {
+			PartJob job = jobs[i];
+			Control control = job.control;
+			if (!control.isDisposed() && !control.getSize().equals(ZERO)
+					&& control.isVisible()) {
+				toRemove.add(job);
+				control.removeListener(SWT.Resize, partListener);
+				control.removeListener(SWT.Activate, partListener);
+				control.removeListener(SWT.Dispose, partListener);
+				job.fire();
+			} else if (control.isDisposed()) {
+				toRemove.add(job);
+			}
+		}
+
+		if (toRemove.isEmpty()) {
+			return;
+		}
+
+		activeControlJobs.removeAll(toRemove);
+	}
+
+	/**
+	 * @param ref
+	 */
+	private void firePartActivated(IWorkbenchPartReference ref) {
+		IWorkbenchPart part = ref.getPart(false);
+		if (part != null) {
+			Control control = deferControl(ref);
+			if (control != null) {
+				addControlListener(control, new PartActivated(ref, control));
+				return;
+			}
+			UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+					part, UIListenerLogging.PE_ACTIVATED);
+			listeners.firePartActivated(part);
+		}
+
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_ACTIVATED);
+		listeners2.firePartActivated(ref);
+	}
+
+	/**
+	 * @param ref
+	 */
+	public void firePartBroughtToTop(IWorkbenchPartReference ref) {
+		IWorkbenchPart part = ref.getPart(false);
+		if (part != null) {
+			Control control = deferControl(ref);
+			if (control != null) {
+				addControlListener(control, new PartTop(ref, control));
+				return;
+			}
+			UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+					part, UIListenerLogging.PE_PART_BROUGHT_TO_TOP);
+			listeners.firePartBroughtToTop(part);
+		}
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_PART_BROUGHT_TO_TOP);
+		listeners2.firePartBroughtToTop(ref);
+	}
+
+	/**
+	 * @param ref
+	 */
+	public void firePartClosed(IWorkbenchPartReference ref) {
+		IWorkbenchPart part = ref.getPart(false);
+		if (part != null) {
+			UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+					part, UIListenerLogging.PE_PART_CLOSED);
+			listeners.firePartClosed(part);
+		}
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_PART_CLOSED);
+		listeners2.firePartClosed(ref);
+	}
+
+	/**
+	 * @param ref
+	 */
+	private void firePartDeactivated(IWorkbenchPartReference ref) {
+		IWorkbenchPart part = ref.getPart(false);
+		if (part != null) {
+			UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+					part, UIListenerLogging.PE_PART_DEACTIVATED);
+			listeners.firePartDeactivated(part);
+		}
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_PART_DEACTIVATED);
+		listeners2.firePartDeactivated(ref);
+	}
+
+	public void firePartVisible(IWorkbenchPartReference ref) {
+		Control control = deferControl(ref);
+		if (control != null) {
+			addControlListener(control, new PartVisible(ref, control));
+			return;
+		}
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_PART_VISIBLE);
+		listeners2.firePartVisible(ref);
+	}
+
+	public void firePartHidden(IWorkbenchPartReference ref) {
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_PART_HIDDEN);
+		listeners2.firePartHidden(ref);
+	}
+
+	public void firePartInputChanged(IWorkbenchPartReference ref) {
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_PART_INPUT_CHANGED);
+		listeners2.firePartInputChanged(ref);
+	}
+
+	/**
+	 * @param ref
+	 */
+	public void firePartOpened(IWorkbenchPartReference ref) {
+		IWorkbenchPart part = ref.getPart(false);
+		if (part != null) {
+			UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+					part, UIListenerLogging.PE_PART_OPENED);
+			listeners.firePartOpened(part);
+		}
+		UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+				UIListenerLogging.PE2_PART_OPENED);
+		listeners2.firePartOpened(ref);
+	}
+
+	public IWorkbenchPart getActivePart() {
+		return activePart == null ? null : activePart.getPart(false);
+	}
+
+	public IWorkbenchPartReference getActivePartReference() {
+		return activePart;
+	}
+
+	public void setActivePart(IWorkbenchPartReference ref) {
+		IWorkbenchPartReference oldRef = activePart;
+
+		// Filter out redundant activation events
+		if (oldRef == ref) {
+			return;
+		}
+
+		if (oldRef != null && oldRef.getPart(false) != null) {
+			firePartDeactivated(oldRef);
+		}
+
+		activePart = ref;
+
+		if (ref != null) {
+			firePartActivated(ref);
+		}
+	}
+
+	public void firePageChanged(PageChangedEvent event) {
+		listeners2.firePageChanged(event);
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java
new file mode 100644
index 0000000..92587cf
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Dan Rubel (dan_rubel@instantiations.com) - accessor to get context menu ids
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.extensions.ModelReference;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.progress.WorkbenchSiteProgressService;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.internal.testing.WorkbenchPartTestable;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceScopes;
+import org.eclipse.ui.testing.IWorkbenchPartTestable;
+
+/**
+ * <code>PartSite</code> is the general implementation for an
+ * <code>IWorkbenchPartSite</code>. A site maintains the context for a part,
+ * including the part, its pane, active contributions, selection provider, etc.
+ * Together, these components make up the complete behavior for a part as if it
+ * was implemented by one person.
+ * 
+ * The <code>PartSite</code> lifecycle is as follows ..
+ * 
+ * <ol>
+ * <li>a site is constructed</li>
+ * <li>a part is constructed and stored in the part</li>
+ * <li>the site calls part.init()</li>
+ * <li>a pane is constructed and stored in the site</li>
+ * <li>the action bars for a part are constructed and stored in the site</li>
+ * <li>the pane is added to a presentation</li>
+ * <li>the SWT widgets for the pane and part are created</li>
+ * <li>the site is activated, causing the actions to become visible</li>
+ * </ol>
+ */
+public abstract class PartSite implements IWorkbenchPartSite {
+
+	/**
+	 * This is a helper method for the register context menu functionality. It
+	 * is provided so that different implementations of the
+	 * <code>IWorkbenchPartSite</code> interface don't have to worry about how
+	 * context menus should work.
+	 * 
+	 * @param menuId
+	 *            the menu id
+	 * @param menuManager
+	 *            the menu manager
+	 * @param selectionProvider
+	 *            the selection provider
+	 * @param includeEditorInput
+	 *            whether editor inputs should be included in the structured
+	 *            selection when calculating contributions
+	 * @param part
+	 *            the part for this site
+	 * @param menuExtenders
+	 *            the collection of menu extenders for this site
+	 * @see IWorkbenchPartSite#registerContextMenu(MenuManager,
+	 *      ISelectionProvider)
+	 */
+	public static final void registerContextMenu(final String menuId,
+			final MenuManager menuManager,
+			final ISelectionProvider selectionProvider,
+			final boolean includeEditorInput, final IWorkbenchPart part,
+			final Collection menuExtenders) {
+		/*
+		 * Check to see if the same menu manager and selection provider have
+		 * already been used. If they have, then we can just add another menu
+		 * identifier to the existing PopupMenuExtender.
+		 */
+		final Iterator extenderItr = menuExtenders.iterator();
+		boolean foundMatch = false;
+		while (extenderItr.hasNext()) {
+			final PopupMenuExtender existingExtender = (PopupMenuExtender) extenderItr
+					.next();
+			if (existingExtender.matches(menuManager, selectionProvider, part)) {
+				existingExtender.addMenuId(menuId);
+				foundMatch = true;
+				break;
+			}
+		}
+
+		if (!foundMatch) {
+			menuExtenders.add(new PopupMenuExtender(menuId, menuManager,
+					selectionProvider, part, includeEditorInput));
+		}
+	}
+
+	private IWorkbenchPartReference partReference;
+
+	private IWorkbenchPart part;
+
+	private IWorkbenchPage page;
+
+	private String extensionID;
+
+	private String pluginID;
+
+	private String extensionName;
+
+	private SubActionBars actionBars;
+
+	private KeyBindingService keyBindingService;
+
+	protected ArrayList menuExtenders;
+
+	private WorkbenchSiteProgressService progressService;
+
+	protected final ServiceLocator serviceLocator;
+
+	final protected IEclipseContext e4Context;
+
+	/**
+	 * Build the part site.
+	 * 
+	 * @param ref
+	 *            the part reference
+	 * @param part
+	 *            the part
+	 * @param page
+	 *            the page it belongs to
+	 */
+	public PartSite(IWorkbenchPartReference ref, IWorkbenchPart part,
+			IWorkbenchPage page) {
+		this.partReference = ref;
+		this.part = part;
+		this.page = page;
+		extensionID = "org.eclipse.ui.UnknownID"; //$NON-NLS-1$
+		extensionName = "Unknown Name"; //$NON-NLS-1$
+
+		// Initialize the service locator.
+		final WorkbenchWindow workbenchWindow = (WorkbenchWindow) page
+				.getWorkbenchWindow();
+		IServiceLocatorCreator slc = (IServiceLocatorCreator) workbenchWindow
+				.getService(IServiceLocatorCreator.class);
+		this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+				workbenchWindow, null, new IDisposable() {
+					public void dispose() {
+						final Control control = getPane().getControl();
+						if (control != null && !control.isDisposed()) {
+							getPane().doHide();
+						}
+					}
+				});
+		e4Context = ((ModelReference) partReference).getModel().getContext();
+		this.serviceLocator.setContext(e4Context);
+
+		initializeDefaultServices();
+	}
+
+	/**
+	 * Initialize the local services.
+	 */
+	private void initializeDefaultServices() {
+		serviceLocator.registerService(IWorkbenchLocationService.class,
+				new WorkbenchLocationService(IServiceScopes.PARTSITE_SCOPE,
+						getWorkbenchWindow().getWorkbench(),
+						getWorkbenchWindow(), this, null, null, 2));
+
+		// local handler service for local handlers
+		IHandlerService handlerService = new LegacyHandlerService(e4Context);
+		serviceLocator.registerService(IHandlerService.class, handlerService);
+
+		// added back for legacy reasons
+		serviceLocator.registerService(IWorkbenchPartSite.class, this);
+		e4Context.set(IWorkbenchSiteProgressService.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						if (progressService == null) {
+							progressService = new WorkbenchSiteProgressService(
+									PartSite.this);
+						}
+						return progressService;
+					}
+				});
+		e4Context.set(IKeyBindingService.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						if (keyBindingService == null) {
+							keyBindingService = new KeyBindingService(
+									PartSite.this);
+						}
+
+						return keyBindingService;
+					}
+				});
+	}
+
+	/**
+	 * Dispose the contributions.
+	 */
+	public void dispose() {
+		if (menuExtenders != null) {
+			HashSet managers = new HashSet(menuExtenders.size());
+			for (int i = 0; i < menuExtenders.size(); i++) {
+				PopupMenuExtender ext = (PopupMenuExtender) menuExtenders
+						.get(i);
+				managers.add(ext.getManager());
+				ext.dispose();
+			}
+			if (managers.size() > 0) {
+				for (Iterator iterator = managers.iterator(); iterator
+						.hasNext();) {
+					MenuManager mgr = (MenuManager) iterator.next();
+					mgr.dispose();
+				}
+			}
+			menuExtenders = null;
+		}
+
+		if (keyBindingService != null) {
+			keyBindingService.dispose();
+			keyBindingService = null;
+		}
+
+		if (progressService != null) {
+			progressService.dispose();
+			progressService = null;
+		}
+
+		if (serviceLocator != null) {
+			serviceLocator.dispose();
+		}
+		part = null;
+	}
+
+	/**
+	 * Returns the action bars for the part. If this part is a view then it has
+	 * exclusive use of the action bars. If this part is an editor then the
+	 * action bars are shared among this editor and other editors of the same
+	 * type.
+	 */
+	public IActionBars getActionBars() {
+		return actionBars;
+	}
+
+	/**
+	 * Returns the part registry extension ID.
+	 * 
+	 * @return the registry extension ID
+	 */
+	public String getId() {
+		return extensionID;
+	}
+
+	/**
+	 * Returns the page containing this workbench site's part.
+	 * 
+	 * @return the page containing this part
+	 */
+	public IWorkbenchPage getPage() {
+		return page;
+	}
+
+	/**
+	 * Gets the part pane.
+	 */
+	public PartPane getPane() {
+		return null;
+	}
+
+	/**
+	 * Returns the part.
+	 */
+	public IWorkbenchPart getPart() {
+		return part;
+	}
+
+	/**
+	 * Returns the part reference.
+	 */
+	public IWorkbenchPartReference getPartReference() {
+		return partReference;
+	}
+
+	/**
+	 * Returns the part registry plugin ID. It cannot be <code>null</code>.
+	 * 
+	 * @return the registry plugin ID
+	 */
+	public String getPluginId() {
+		return pluginID;
+	}
+
+	/**
+	 * Returns the registered name for this part.
+	 */
+	public String getRegisteredName() {
+		return extensionName;
+	}
+
+	/**
+	 * Returns the selection provider for a part.
+	 */
+	public ISelectionProvider getSelectionProvider() {
+		return (ISelectionProvider) e4Context.get(ISelectionProvider.class
+				.getName());
+	}
+
+	/**
+	 * Returns the shell containing this part.
+	 * 
+	 * @return the shell containing this part
+	 */
+	public Shell getShell() {
+		return page.getWorkbenchWindow().getShell();
+	}
+
+	/**
+	 * Returns the workbench window containing this part.
+	 * 
+	 * @return the workbench window containing this part
+	 */
+	public IWorkbenchWindow getWorkbenchWindow() {
+		return page.getWorkbenchWindow();
+	}
+
+	/**
+	 * Register a popup menu for extension.
+	 */
+	public void registerContextMenu(String menuID, MenuManager menuMgr,
+			ISelectionProvider selProvider) {
+		if (menuExtenders == null) {
+			menuExtenders = new ArrayList(1);
+		}
+
+		registerContextMenu(menuID, menuMgr, selProvider, true, getPart(),
+				menuExtenders);
+	}
+
+	/**
+	 * Register a popup menu with the default id for extension.
+	 */
+	public void registerContextMenu(MenuManager menuMgr,
+			ISelectionProvider selProvider) {
+		registerContextMenu(getId(), menuMgr, selProvider);
+	}
+
+	// getContextMenuIds() added by Dan Rubel (dan_rubel@instantiations.com)
+	/**
+	 * Get the registered popup menu identifiers
+	 */
+	public String[] getContextMenuIds() {
+		if (menuExtenders == null) {
+			return new String[0];
+		}
+		ArrayList menuIds = new ArrayList(menuExtenders.size());
+		for (Iterator iter = menuExtenders.iterator(); iter.hasNext();) {
+			final PopupMenuExtender extender = (PopupMenuExtender) iter.next();
+			menuIds.addAll(extender.getMenuIds());
+		}
+		return (String[]) menuIds.toArray(new String[menuIds.size()]);
+	}
+
+	/**
+	 * Sets the action bars for the part.
+	 */
+	public void setActionBars(SubActionBars bars) {
+		e4Context.set(IActionBars.class.getName(), bars);
+		actionBars = bars;
+	}
+
+	/**
+	 * Sets the configuration element for a part.
+	 */
+	public void setConfigurationElement(IConfigurationElement configElement) {
+
+		// Get extension ID.
+		extensionID = configElement.getAttribute("id"); //$NON-NLS-1$
+
+		// Get plugin ID.
+		pluginID = configElement.getNamespace();
+
+		// Get extension name.
+		String name = configElement.getAttribute("name"); //$NON-NLS-1$
+		if (name != null) {
+			extensionName = name;
+		}
+	}
+
+	protected void setPluginId(String pluginId) {
+		this.pluginID = pluginId;
+	}
+
+	/**
+	 * Sets the part registry extension ID.
+	 * 
+	 * @param id
+	 *            the registry extension ID
+	 */
+	protected void setId(String id) {
+		extensionID = id;
+	}
+
+	/**
+	 * Sets the part.
+	 */
+	public void setPart(IWorkbenchPart newPart) {
+		part = newPart;
+	}
+
+	/**
+	 * Sets the registered name for this part.
+	 * 
+	 * @param name
+	 *            the registered name
+	 */
+	protected void setRegisteredName(String name) {
+		extensionName = name;
+	}
+
+	/**
+	 * Set the selection provider for a part.
+	 */
+	public void setSelectionProvider(ISelectionProvider provider) {
+		e4Context.set(ISelectionProvider.class.getName(), provider);
+		if (provider != null) {
+			provider
+					.addSelectionChangedListener(new ISelectionChangedListener() {
+						public void selectionChanged(SelectionChangedEvent event) {
+							e4Context.modify(IServiceConstants.SELECTION, event
+									.getSelection());
+						}
+					});
+		}
+	}
+
+	/*
+	 * @see IWorkbenchPartSite#getKeyBindingService()
+	 */
+	public IKeyBindingService getKeyBindingService() {
+		return (IKeyBindingService) e4Context.get(IKeyBindingService.class
+				.getName());
+	}
+
+	protected String getInitialScopeId() {
+		return null;
+	}
+
+	/**
+	 * Get an adapter for this type.
+	 * 
+	 * @param adapter
+	 * @return
+	 */
+	public final Object getAdapter(Class adapter) {
+
+		if (IWorkbenchSiteProgressService.class == adapter) {
+			return getSiteProgressService();
+		}
+
+		if (IWorkbenchPartTestable.class == adapter) {
+			return new WorkbenchPartTestable(this);
+		}
+
+		return Platform.getAdapterManager().getAdapter(this, adapter);
+	}
+
+	public void activateActionBars(boolean forceVisibility) {
+		if (serviceLocator != null) {
+			serviceLocator.activate();
+		}
+
+		if (actionBars != null) {
+			actionBars.activate(forceVisibility);
+		}
+	}
+
+	public void deactivateActionBars(boolean forceHide) {
+		if (actionBars != null) {
+			actionBars.deactivate(forceHide);
+		}
+		if (serviceLocator != null) {
+			serviceLocator.deactivate();
+		}
+	}
+
+	/**
+	 * Get a progress service for the receiver.
+	 * 
+	 * @return WorkbenchSiteProgressService
+	 */
+	WorkbenchSiteProgressService getSiteProgressService() {
+		return (WorkbenchSiteProgressService) e4Context
+				.get(IWorkbenchSiteProgressService.class.getName());
+	}
+
+	public final Object getService(final Class key) {
+		return serviceLocator.getService(key);
+	}
+
+	public final boolean hasService(final Class key) {
+		return serviceLocator.hasService(key);
+	}
+
+	/**
+	 * Prints out the identifier, the plug-in identifier and the registered
+	 * name. This is for debugging purposes only.
+	 * 
+	 * @since 3.2
+	 */
+	public String toString() {
+		final StringBuffer buffer = new StringBuffer();
+		buffer.append("PartSite(id="); //$NON-NLS-1$
+		buffer.append(getId());
+		buffer.append(",pluginId="); //$NON-NLS-1$
+		buffer.append(getPluginId());
+		buffer.append(",registeredName="); //$NON-NLS-1$
+		buffer.append(getRegisteredName());
+		buffer.append(",hashCode="); //$NON-NLS-1$
+		buffer.append(hashCode());
+		buffer.append(')');
+		return buffer.toString();
+	}
+
+	public IEclipseContext getContext() {
+		return e4Context;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartsEventTransformer.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartsEventTransformer.java
new file mode 100644
index 0000000..e16dfe5
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartsEventTransformer.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.e4.ui.model.application.MEditorStack;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MViewStack;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.SubActionBars;
+
+/**
+ * Transforms E4 MPart events into 3.x legacy events.
+ */
+public class PartsEventTransformer extends EContentAdapter {
+
+	final private IEclipseContext e4Context;
+	final private WorkbenchPagePartList partList;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param e4Context
+	 * @param partList
+	 */
+	public PartsEventTransformer(IEclipseContext e4Context,
+			WorkbenchPagePartList partList) {
+		this.e4Context = e4Context;
+		this.partList = partList;
+	}
+
+	public void notifyChanged(Notification notification) {
+		super.notifyChanged(notification);
+
+		/*
+		 * We create partOpened / partClosed events based on both MPartWidget
+		 * events.
+		 * 
+		 * The initial MPartVisible events are sent early and don't have the
+		 * actual implementation included. The MPartWidget events are sent as a
+		 * final step of "part is created" and therefore we use it to create
+		 * partOpened events. When the part is closed the widget is set to null.
+		 */
+		if (MApplicationPackage.Literals.UI_ELEMENT__WIDGET.equals(notification
+				.getFeature())) {
+			if (notification.getEventType() != Notification.SET)
+				return;
+			if (notification.getOldValue() == notification.getNewValue())
+				return; // avoid extra notifications
+			Object part = notification.getNotifier();
+			if (part instanceof MPart) {
+				IWorkbenchPartReference ref = toPartRef((MPart) part);
+				if (ref != null) {
+					boolean isVisible = ((MPart) part).isVisible();
+					if (isVisible) {
+						if (notification.getNewValue() == null) {
+							/*
+							 * not sure if this is the right place to fix bug
+							 * 283922 but if there is no widget and
+							 * isVisible==true, we must be shutting down, and we
+							 * should not send partOpened notifications.
+							 */
+							return;
+						}
+						SaveablesList modelManager = (SaveablesList) ref
+								.getPart(true).getSite().getService(
+										ISaveablesLifecycleListener.class);
+						modelManager.postOpen(ref.getPart(true));
+						partList.firePartOpened(ref);
+					}
+				}
+			}
+			return;
+		}
+
+		// Interpret E4 activation events:
+		if (!MApplicationPackage.Literals.ELEMENT_CONTAINER__ACTIVE_CHILD
+				.equals(notification.getFeature()))
+			return;
+
+		// at this time we only interpreting SET events
+		if (notification.getEventType() != Notification.SET
+				|| notification.getEventType() != Notification.CREATE)
+			return;
+
+		// make sure something actually changed
+		Object oldPart = notification.getOldValue();
+		Object newPart = notification.getNewValue();
+
+		// create 3.x visibility events
+		if ((newPart != oldPart) && (oldPart instanceof MPart)
+				&& (newPart instanceof MPart))
+			changeVisibility((MPart) oldPart, (MPart) newPart);
+
+		// create 3.x activation events
+		final Object object = e4Context.get(IServiceConstants.ACTIVE_PART);
+		if ((newPart != oldPart) && newPart instanceof MPerspective) {
+			// let legacy Workbench know about perspective activation
+			IWorkbenchPage page = (IWorkbenchPage) e4Context
+					.get(IWorkbenchPage.class.getName());
+			if (page != null) {
+				String id = ((MPerspective) newPart).getId();
+				IPerspectiveDescriptor[] descriptors = page
+						.getOpenPerspectives();
+				for (IPerspectiveDescriptor desc : descriptors) {
+					if (!id.equals(desc.getId()))
+						continue;
+					page.setPerspective(desc);
+				}
+			}
+		}
+		if (object instanceof MPart) {
+			IWorkbenchPartReference ref = toPartRef((MPart) object);
+			if (ref != null) {
+				// set the Focus to the newly active part
+				IWorkbenchPart part = ref.getPart(true);
+				part.setFocus();
+				// Update the action bars
+				SubActionBars bars = (SubActionBars) ((PartSite) part.getSite())
+						.getActionBars();
+				bars.partChanged(part);
+				partList.setActivePart(ref);
+				if (ref instanceof IEditorReference) {
+					IEditorReference editorReference = (IEditorReference) ref;
+					partList.setActiveEditor(editorReference);
+					final IEditorPart editor = editorReference.getEditor(true);
+					e4Context.set(ISources.ACTIVE_EDITOR_NAME, editor);
+					e4Context.set(ISources.ACTIVE_EDITOR_ID_NAME, editor
+							.getSite().getId());
+					e4Context.set(ISources.ACTIVE_EDITOR_INPUT_NAME, editor
+							.getEditorInput());
+				}
+			}
+		} else {
+			partList.setActiveEditor(null);
+			e4Context.set(ISources.ACTIVE_EDITOR_NAME, null);
+			e4Context.set(ISources.ACTIVE_EDITOR_ID_NAME, null);
+			e4Context.set(ISources.ACTIVE_EDITOR_INPUT_NAME, null);
+			partList.setActivePart(null);
+		}
+	}
+
+	// TBD default hidden/shown state
+	private void changeVisibility(MPart oldPart, MPart newPart) {
+		// TBD old parent vs new parent: should we apply the same logic to both?
+		// if parent was a stack: hide the previously active part
+		MElementContainer oldParent = oldPart.getParent();
+		if (oldParent instanceof MViewStack
+				|| oldParent instanceof MEditorStack)
+			visiblityChange(oldPart, false);
+		// show new part
+		visiblityChange(newPart, true);
+	}
+
+	private void visiblityChange(MPart part, boolean visible) {
+		IWorkbenchPartReference partRef = toPartRef(part);
+		if (visible) {
+			// TBD do we need to make children/parents visible or will there be
+			// separate notifications?
+			if (partRef != null)
+				partList.firePartVisible(partRef); // make this part visible
+		} else {
+			if (partRef != null)
+				partList.firePartHidden(partRef); // hide this part
+		}
+	}
+
+	// TBD is this the best method?
+	// TBD this should be a general utility method somewhere in the fragment
+	private IWorkbenchPartReference toPartRef(MPart part) {
+		if (part == null)
+			return null;
+		Object impl = part.getObject();
+		if (!(impl instanceof IWorkbenchPart))
+			return null;
+		PartSite site = (PartSite) ((IWorkbenchPart) impl).getSite();
+		return site.getPartReference();
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Perspective.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Perspective.java
new file mode 100644
index 0000000..02e05f9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Perspective.java
@@ -0,0 +1,2611 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Markus Alexander Kuppe, Versant GmbH - bug 215797
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.compatibility.LegacyView;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.extensions.ModelViewReference;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MPerspectiveStack;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewSashContainer;
+import org.eclipse.e4.ui.model.application.MViewStack;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.Geometry;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.intro.IIntroConstants;
+import org.eclipse.ui.internal.layout.ITrimManager;
+import org.eclipse.ui.internal.layout.IWindowTrim;
+import org.eclipse.ui.internal.layout.TrimLayout;
+import org.eclipse.ui.internal.misc.StatusUtil;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
+import org.eclipse.ui.internal.registry.PerspectiveExtensionReader;
+import org.eclipse.ui.internal.registry.PerspectiveRegistry;
+import org.eclipse.ui.internal.util.PrefUtil;
+import org.eclipse.ui.presentations.AbstractPresentationFactory;
+import org.eclipse.ui.presentations.IStackPresentationSite;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.views.IStickyViewDescriptor;
+import org.eclipse.ui.views.IViewDescriptor;
+import org.eclipse.ui.views.IViewRegistry;
+
+/**
+ * The ViewManager is a factory for workbench views.
+ */
+public class Perspective {
+	protected PerspectiveDescriptor descriptor;
+
+	protected WorkbenchPage page;
+
+	// Editor Area management
+	protected LayoutPart editorArea;
+	protected PartPlaceholder editorHolder;
+	protected boolean editorHidden = false;
+	protected boolean editorAreaRestoreOnUnzoom = false;
+	protected int editorAreaState = IStackPresentationSite.STATE_RESTORED;
+
+	private ViewFactory viewFactory;
+
+	protected ArrayList alwaysOnActionSets;
+
+	protected ArrayList alwaysOffActionSets;
+
+	protected ArrayList newWizardShortcuts;
+
+	protected ArrayList showViewShortcuts;
+
+	protected ArrayList perspectiveShortcuts;
+
+	/** IDs of menu items the user has chosen to hide */
+	protected Collection hideMenuIDs;
+
+	/** IDs of toolbar items the user has chosen to hide */
+	protected Collection hideToolBarIDs;
+
+	// private List fastViews;
+	protected FastViewManager fastViewManager = null;
+
+	private Map mapIDtoViewLayoutRec;
+
+	protected boolean fixed;
+
+	protected ArrayList showInPartIds;
+
+	protected HashMap showInTimes = new HashMap();
+
+	private IViewReference activeFastView;
+
+	protected IMemento memento;
+
+	protected PerspectiveHelper presentation;
+
+	final static private String VERSION_STRING = "0.016";//$NON-NLS-1$
+
+	private FastViewPane fastViewPane = new FastViewPane();
+
+	// fields used by fast view resizing via a sash
+	private static final int FASTVIEW_HIDE_STEPS = 5;
+
+	/**
+	 * Reference to the part that was previously active when this perspective
+	 * was deactivated.
+	 */
+	private IWorkbenchPartReference oldPartRef = null;
+
+	protected boolean shouldHideEditorsOnActivate = false;
+
+	protected ModeledPageLayout layout;
+
+	/**
+	 * ViewManager constructor comment.
+	 */
+	public Perspective(PerspectiveDescriptor desc, WorkbenchPage page)
+			throws WorkbenchException {
+		this(page);
+		descriptor = desc;
+		if (desc != null) {
+			createPresentation(desc);
+		}
+	}
+
+	/**
+	 * ViewManager constructor comment.
+	 */
+	protected Perspective(WorkbenchPage page) throws WorkbenchException {
+		this.page = page;
+		this.viewFactory = page.getViewFactory();
+		alwaysOnActionSets = new ArrayList(2);
+		alwaysOffActionSets = new ArrayList(2);
+		hideMenuIDs = new HashSet();
+		hideToolBarIDs = new HashSet();
+
+		// We'll only make a FastView Manager if there's a
+		// Trim manager in the WorkbenchWindow
+		IWorkbenchWindow wbw = page.getWorkbenchWindow();
+		if (wbw instanceof WorkbenchWindow) {
+			if (((WorkbenchWindow) wbw).getTrimManager() != null)
+				fastViewManager = new FastViewManager(this, page);
+		}
+
+		mapIDtoViewLayoutRec = new HashMap();
+	}
+
+	/**
+	 * Sets the fast view attribute. Note: The page is expected to update action
+	 * bars.
+	 */
+	public void makeFastView(IViewReference ref) {
+		addFastView(ref, true);
+	}
+
+	/**
+	 * Sets the fast view attribute. Note: The page is expected to update action
+	 * bars.
+	 */
+	public void addFastView(IViewReference ref, boolean handleLayout) {
+		ViewPane pane = (ViewPane) ((WorkbenchPartReference) ref).getPane();
+		if (!isFastView(ref)) {
+			if (handleLayout) {
+				// Only remove the part from the presentation if it
+				// is actually in the presentation.
+				if (presentation.hasPlaceholder(ref.getId(), ref
+						.getSecondaryId())
+						|| pane.getContainer() != null) {
+					presentation.removePart(pane);
+				}
+			}
+
+			// We are drag-enabling the pane because it has been disabled
+			// when it was removed from the perspective presentation.
+			pane.setFast(true);
+			Control ctrl = pane.getControl();
+			if (ctrl != null) {
+				ctrl.setEnabled(false); // Remove focus support.
+			}
+		}
+	}
+
+	/**
+	 * Moves a part forward in the Z order of a perspective so it is visible.
+	 * 
+	 * @param part
+	 *            the part to bring to move forward
+	 * @return true if the part was brought to top, false if not.
+	 */
+	public boolean bringToTop(IViewReference ref) {
+		if (isFastView(ref)) {
+			setActiveFastView(ref);
+			return true;
+		} else {
+			return presentation.bringPartToTop(getPane(ref));
+		}
+	}
+
+	/**
+	 * Returns whether a view exists within the perspective.
+	 */
+	public boolean containsView(IViewPart view) {
+		IViewSite site = view.getViewSite();
+		IViewReference ref = findView(site.getId(), site.getSecondaryId());
+		if (ref == null) {
+			return false;
+		}
+		return (view == ref.getPart(false));
+	}
+
+	/**
+	 * Create the initial list of action sets.
+	 */
+	protected void createInitialActionSets(List outputList, List stringList) {
+		ActionSetRegistry reg = WorkbenchPlugin.getDefault()
+				.getActionSetRegistry();
+		Iterator iter = stringList.iterator();
+		while (iter.hasNext()) {
+			String id = (String) iter.next();
+			IActionSetDescriptor desc = reg.findActionSet(id);
+			if (desc != null) {
+				outputList.add(desc);
+			} else {
+				WorkbenchPlugin.log("Unable to find Action Set: " + id);//$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Create a presentation for a perspective.
+	 */
+	private void createPresentation(PerspectiveDescriptor persp)
+			throws WorkbenchException {
+		if (persp.hasCustomDefinition()) {
+			loadCustomPersp(persp);
+		} else {
+			loadPredefinedPersp(persp);
+		}
+	}
+
+	/**
+	 * Dispose the perspective and all views contained within.
+	 */
+	public void dispose() {
+		// Get rid of presentation.
+		if (presentation == null) {
+			disposeViewRefs();
+			return;
+		}
+
+		presentation.deactivate();
+		presentation.dispose();
+
+		fastViewPane.dispose();
+
+		// Release each view.
+		IViewReference refs[] = getViewReferences();
+		for (int i = 0, length = refs.length; i < length; i++) {
+			getViewFactory().releaseView(refs[i]);
+		}
+
+		mapIDtoViewLayoutRec.clear();
+	}
+
+	private void disposeViewRefs() {
+		if (memento == null) {
+			return;
+		}
+		IMemento views[] = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+		for (int x = 0; x < views.length; x++) {
+			// Get the view details.
+			IMemento childMem = views[x];
+			String id = childMem.getString(IWorkbenchConstants.TAG_ID);
+			// skip creation of the intro reference - it's handled elsewhere.
+			if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
+				continue;
+			}
+
+			String secondaryId = ViewFactory.extractSecondaryId(id);
+			if (secondaryId != null) {
+				id = ViewFactory.extractPrimaryId(id);
+			}
+			// Create and open the view.
+
+			if (!"true".equals(childMem.getString(IWorkbenchConstants.TAG_REMOVED))) { //$NON-NLS-1$
+				IViewReference ref = viewFactory.getView(id, secondaryId);
+				if (ref != null) {
+					viewFactory.releaseView(ref);
+				}
+			}
+
+		}
+	}
+
+	/**
+	 * Finds the view with the given ID that is open in this page, or
+	 * <code>null</code> if not found.
+	 * 
+	 * @param viewId
+	 *            the view ID
+	 */
+	public IViewReference findView(String viewId) {
+		return findView(viewId, null);
+	}
+
+	/**
+	 * Finds the view with the given id and secondary id that is open in this
+	 * page, or <code>null</code> if not found.
+	 * 
+	 * @param viewId
+	 *            the view ID
+	 * @param secondaryId
+	 *            the secondary ID
+	 */
+	public IViewReference findView(String id, String secondaryId) {
+		IViewReference refs[] = getViewReferences();
+		for (int i = 0; i < refs.length; i++) {
+			IViewReference ref = refs[i];
+			if (id.equals(ref.getId())
+					&& (secondaryId == null ? ref.getSecondaryId() == null
+							: secondaryId.equals(ref.getSecondaryId()))) {
+				return ref;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the window's client composite widget which views and editor area
+	 * will be parented.
+	 */
+	public Composite getClientComposite() {
+		return page.getClientComposite();
+	}
+
+	/**
+	 * Returns the perspective.
+	 */
+	public IPerspectiveDescriptor getDesc() {
+		return descriptor;
+	}
+
+	/**
+	 * Returns the bounds of the given fast view.
+	 */
+	/* package */Rectangle getFastViewBounds(IViewReference ref) {
+		// Copy the bounds of the page composite
+		Rectangle bounds = page.getClientComposite().getBounds();
+		// get the width ratio of the fast view
+		float ratio = getFastViewWidthRatio(ref);
+		// Compute the actual width of the fast view.
+		bounds.width = (int) (ratio * getClientComposite().getSize().x);
+		return bounds;
+	}
+
+	/**
+	 * Returns the docked views.
+	 */
+	public IViewReference[] getFastViews() {
+		if (fastViewManager == null)
+			return new IViewReference[0];
+
+		List trueFVBRefs = fastViewManager
+				.getFastViews(FastViewBar.FASTVIEWBAR_ID);
+		IViewReference array[] = new IViewReference[trueFVBRefs.size()];
+		trueFVBRefs.toArray(array);
+		return array;
+	}
+
+	/**
+	 * Returns the new wizard shortcuts associated with this perspective.
+	 * 
+	 * @return an array of new wizard identifiers
+	 */
+	public String[] getNewWizardShortcuts() {
+		return (String[]) newWizardShortcuts
+				.toArray(new String[newWizardShortcuts.size()]);
+	}
+
+	/**
+	 * Returns the pane for a view reference.
+	 */
+	protected ViewPane getPane(IViewReference ref) {
+		return null;
+	}
+
+	/**
+	 * Returns the perspective shortcuts associated with this perspective.
+	 * 
+	 * @return an array of perspective identifiers
+	 */
+	public String[] getPerspectiveShortcuts() {
+		return (String[]) perspectiveShortcuts
+				.toArray(new String[perspectiveShortcuts.size()]);
+	}
+
+	/**
+	 * Returns the presentation.
+	 */
+	public PerspectiveHelper getPresentation() {
+		return presentation;
+	}
+
+	/**
+	 * Retrieves the fast view width ratio for the given view. If the ratio is
+	 * not known, the default ratio for the view is assigned and returned.
+	 */
+	public float getFastViewWidthRatio(IViewReference ref) {
+		ViewLayoutRec rec = getViewLayoutRec(ref, true);
+		if (rec.fastViewWidthRatio == IPageLayout.INVALID_RATIO) {
+			IViewRegistry reg = WorkbenchPlugin.getDefault().getViewRegistry();
+			IViewDescriptor desc = reg.find(ref.getId());
+			rec.fastViewWidthRatio = (desc != null ? desc
+					.getFastViewWidthRatio()
+					: IPageLayout.DEFAULT_FASTVIEW_RATIO);
+		}
+		return rec.fastViewWidthRatio;
+	}
+
+	/**
+	 * Returns the ids of the parts to list in the Show In... dialog. This is a
+	 * List of Strings.
+	 */
+	public ArrayList getShowInPartIds() {
+		return showInPartIds;
+	}
+
+	/**
+	 * Returns the time at which the last Show In was performed for the given
+	 * target part, or 0 if unknown.
+	 */
+	public long getShowInTime(String partId) {
+		Long t = (Long) showInTimes.get(partId);
+		return t == null ? 0L : t.longValue();
+	}
+
+	/**
+	 * Returns the show view shortcuts associated with this perspective.
+	 * 
+	 * @return an array of view identifiers
+	 */
+	public String[] getShowViewShortcuts() {
+		return (String[]) showViewShortcuts
+				.toArray(new String[showViewShortcuts.size()]);
+	}
+
+	/**
+	 * Returns the view factory.
+	 */
+	public ViewFactory getViewFactory() {
+		return viewFactory;
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IViewReference[] getViewReferences() {
+		// Get normal views.
+		if (presentation == null) {
+			return new IViewReference[0];
+		}
+
+		List panes = new ArrayList(5);
+		presentation.collectViewPanes(panes);
+
+		List fastViews = (fastViewManager != null) ? fastViewManager
+				.getFastViews(null) : new ArrayList();
+		IViewReference[] resultArray = new IViewReference[panes.size()
+				+ fastViews.size()];
+
+		// Copy fast views.
+		int nView = 0;
+		for (int i = 0; i < fastViews.size(); i++) {
+			resultArray[nView] = (IViewReference) fastViews.get(i);
+			++nView;
+		}
+
+		// Copy normal views.
+		for (int i = 0; i < panes.size(); i++) {
+			ViewPane pane = (ViewPane) panes.get(i);
+			resultArray[nView] = pane.getViewReference();
+			++nView;
+		}
+
+		return resultArray;
+	}
+
+	/**
+	 * Hide the editor area if visible
+	 */
+	protected void hideEditorArea() {
+		if (!isEditorAreaVisible()) {
+			return;
+		}
+
+		// Show the editor in the appropriate location
+		if (useNewMinMax(this)) {
+			// If it's the currently maximized part we have to restore first
+			if (getPresentation().getMaximizedStack() instanceof EditorStack) {
+				getPresentation().getMaximizedStack().setState(
+						IStackPresentationSite.STATE_RESTORED);
+			}
+
+			boolean isMinimized = editorAreaState == IStackPresentationSite.STATE_MINIMIZED;
+			if (!isMinimized)
+				hideEditorAreaLocal();
+			else
+				setEditorAreaTrimVisibility(false);
+		} else {
+			hideEditorAreaLocal();
+		}
+
+		editorHidden = true;
+	}
+
+	/**
+	 * Hide the editor area if visible
+	 */
+	protected void hideEditorAreaLocal() {
+		if (editorHolder != null) {
+			return;
+		}
+
+		// Replace the editor area with a placeholder so we
+		// know where to put it back on show editor area request.
+		editorHolder = new PartPlaceholder(editorArea.getID());
+		presentation.getLayout().replace(editorArea, editorHolder);
+	}
+
+	/**
+	 * Hides a fast view. The view shrinks equally <code>steps</code> times
+	 * before disappearing completely.
+	 */
+	private void hideFastView(IViewReference ref, int steps) {
+		setFastViewIconSelection(ref, false);
+
+		// Note: We always do at least one step of the animation.
+		// Note: This doesn't take into account the overhead of doing
+		if (ref == activeFastView) {
+			saveFastViewWidthRatio();
+			fastViewPane.hideView();
+		}
+	}
+
+	/**
+	 * Hides the fast view sash for zooming in a fast view.
+	 */
+	void hideFastViewSash() {
+		fastViewPane.hideFastViewSash();
+	}
+
+	public boolean hideView(IViewReference ref) {
+		// If the view is locked just return.
+		ModelViewReference mvr = (ModelViewReference) ref;
+		mvr.getModel().setVisible(false);
+		return true;
+	}
+
+	/*
+	 * Return whether the editor area is visible or not.
+	 */
+	protected boolean isEditorAreaVisible() {
+		return !editorHidden;
+	}
+
+	/**
+	 * Returns true if a view is fast.
+	 */
+	public boolean isFastView(IViewReference ref) {
+		if (fastViewManager == null)
+			return false;
+
+		return fastViewManager.isFastView(ref);
+	}
+
+	/**
+	 * Returns the view layout rec for the given view reference, or null if not
+	 * found. If create is true, it creates the record if not already created.
+	 */
+	public ViewLayoutRec getViewLayoutRec(IViewReference ref, boolean create) {
+		ViewLayoutRec result = getViewLayoutRec(ViewFactory.getKey(ref), create);
+		if (result == null && create == false) {
+			result = getViewLayoutRec(ref.getId(), false);
+		}
+		return result;
+	}
+
+	/**
+	 * Returns the view layout record for the given view id or null if not
+	 * found. If create is true, it creates the record if not already created.
+	 */
+	private ViewLayoutRec getViewLayoutRec(String viewId, boolean create) {
+		ViewLayoutRec rec = (ViewLayoutRec) mapIDtoViewLayoutRec.get(viewId);
+		if (rec == null && create) {
+			rec = new ViewLayoutRec();
+			mapIDtoViewLayoutRec.put(viewId, rec);
+		}
+		return rec;
+	}
+
+	/**
+	 * Returns true if a layout or perspective is fixed.
+	 */
+	public boolean isFixedLayout() {
+		// @issue is there a difference between a fixed
+		// layout and a fixed perspective?? If not the API
+		// may need some polish, WorkbenchPage, PageLayout
+		// and Perspective all have isFixed methods.
+		// PageLayout and Perspective have their own fixed
+		// attribute, we are assuming they are always in sync.
+		// WorkbenchPage delegates to the perspective.
+		return fixed;
+	}
+
+	/**
+	 * Returns true if a view is standalone.
+	 * 
+	 * @since 3.0
+	 */
+	public boolean isStandaloneView(IViewReference ref) {
+		ViewLayoutRec rec = getViewLayoutRec(ref, false);
+		return rec != null && rec.isStandalone;
+	}
+
+	/**
+	 * Returns whether the title for a view should be shown. This applies only
+	 * to standalone views.
+	 * 
+	 * @since 3.0
+	 */
+	public boolean getShowTitleView(IViewReference ref) {
+		ViewLayoutRec rec = getViewLayoutRec(ref, false);
+		return rec != null && rec.showTitle;
+	}
+
+	/**
+	 * Creates a new presentation from a persistence file. Note: This method
+	 * should not modify the current state of the perspective.
+	 */
+	private void loadCustomPersp(PerspectiveDescriptor persp) {
+		// get the layout from the registry
+		PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
+				.getDefault().getPerspectiveRegistry();
+		try {
+			IMemento memento = perspRegistry.getCustomPersp(persp.getId());
+			// Restore the layout state.
+			MultiStatus status = new MultiStatus(
+					PlatformUI.PLUGIN_ID,
+					IStatus.OK,
+					NLS
+							.bind(
+									WorkbenchMessages.Perspective_unableToRestorePerspective,
+									persp.getLabel()), null);
+			status.merge(restoreState(memento));
+			status.merge(restoreState());
+			if (status.getSeverity() != IStatus.OK) {
+				unableToOpenPerspective(persp, status);
+			}
+		} catch (IOException e) {
+			unableToOpenPerspective(persp, null);
+		} catch (WorkbenchException e) {
+			unableToOpenPerspective(persp, e.getStatus());
+		}
+	}
+
+	private void unableToOpenPerspective(PerspectiveDescriptor persp,
+			IStatus status) {
+		PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
+				.getDefault().getPerspectiveRegistry();
+		perspRegistry.deletePerspective(persp);
+		// If this is a predefined perspective, we will not be able to delete
+		// the perspective (we wouldn't want to). But make sure to delete the
+		// customized portion.
+		persp.deleteCustomDefinition();
+		String title = WorkbenchMessages.Perspective_problemRestoringTitle;
+		String msg = WorkbenchMessages.Perspective_errorReadingState;
+		if (status == null) {
+			MessageDialog.openError((Shell) null, title, msg);
+		} else {
+			ErrorDialog.openError((Shell) null, title, msg, status);
+		}
+	}
+
+	/**
+	 * Create a presentation for a perspective. Note: This method should not
+	 * modify the current state of the perspective.
+	 */
+	protected void loadPredefinedPersp(PerspectiveDescriptor persp)
+			throws WorkbenchException {
+		// Create layout engine.
+		IPerspectiveFactory factory = null;
+		try {
+			factory = persp.createFactory();
+		} catch (CoreException e) {
+			throw new WorkbenchException(NLS.bind(
+					WorkbenchMessages.Perspective_unableToLoad, persp.getId()));
+		}
+
+		/*
+		 * IPerspectiveFactory#createFactory() can return null
+		 */
+		if (factory == null) {
+			throw new WorkbenchException(NLS.bind(
+					WorkbenchMessages.Perspective_unableToLoad, persp.getId()));
+		}
+
+		MWindow e4Window = page.getModelWindow();
+
+		EList e4Kids = e4Window.getChildren();
+		if (e4Kids.size() == 0) {
+			createLegacyWBModel(e4Window);
+		}
+
+		// Add the new perspective to its stack
+		MElementContainer<MUIElement> perspStack = (MElementContainer<MUIElement>) ModeledPageLayout
+				.findElementById(e4Window, "PerspectiveStack"); //$NON-NLS-1$
+
+		// Is it already there?
+		MPerspective perspModel = (MPerspective) ModeledPageLayout.findPart(
+				perspStack, persp.getId());
+		if (perspModel != null) {
+			if (!perspModel.isVisible())
+				perspModel.setVisible(true);
+			perspStack.setActiveChild(perspModel);
+			return;
+		}
+
+		// Not there, create it
+		perspModel = MApplicationFactory.eINSTANCE.createPerspective();
+		perspModel.setId(persp.getId());
+
+		IConfigurationElement element = persp.getConfigElement();
+		if (element != null) {
+			// Convert the relative path into a bundle URI
+			String imagePath = element.getAttribute("icon"); //$NON-NLS-1$
+			if (imagePath != null) {
+				imagePath = imagePath.replace("$nl$", ""); //$NON-NLS-1$//$NON-NLS-2$
+				if (imagePath.charAt(0) != '/') {
+					imagePath = '/' + imagePath;
+				}
+				String bundleId = element.getContributor().getName();
+				String imageURI = "platform:/plugin/" + bundleId + imagePath; //$NON-NLS-1$
+				perspModel.setIconURI(imageURI);
+			}
+		}
+
+		// e4Window.getChildren().add(persModel);
+		perspModel.setName(persp.getLabel());
+		layout = new ModeledPageLayout(perspModel);
+		((ModeledPageLayout) layout).setDescriptor(descriptor);
+		newWizardShortcuts = layout.getNewWizardShortcuts();
+		showViewShortcuts = layout.getShowViewShortcuts();
+		perspectiveShortcuts = layout.getPerspectiveShortcuts();
+		showInPartIds = layout.getShowInPartIds();
+		// hideMenuIDs = layout.getHiddenMenuItems();
+		// hideToolBarIDs = layout.getHiddenToolBarItems();
+		layout.setFixed(descriptor.getFixed());
+
+		// add the placeholders for the sticky folders and their contents
+
+		// Run layout engine.
+		factory.createInitialLayout(layout);
+		loadExtensions(perspModel, ((ModeledPageLayout) layout));
+		//		MPart ea = ModeledPageLayout.findPart(persModel, "bottom"); //$NON-NLS-1$
+		// if (ea == null) {
+		// layout
+		// .createPlaceholderFolder(
+		//							"bottom", IPageLayout.BOTTOM, 0.2f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+		// }
+		perspStack.getChildren().add(perspModel);
+		perspStack.setActiveChild(perspModel);
+
+		final IEclipseContext perspContext = perspModel.getContext();
+		// Manage the 'close' button
+		// final MPerspective thePerspModel = perspModel;
+		// final PerspectiveDescriptor theDesc = descriptor;
+		// IValueFunction closeFunc = new IValueFunction() {
+		// public Object getValue() {
+		// if (page.getOpenPerspectives().length == 1)
+		// return false;
+		//
+		// ArrayList<IEditorReference> result = new
+		// ArrayList<IEditorReference>();
+		// page.getContainedEditorRefs(result, thePerspModel);
+		// IEditorReference[] openEditors = new IEditorReference[result
+		// .size()];
+		// result.toArray(openEditors);
+		// boolean okToClose = page.closeEditors(openEditors, true);
+		// if (okToClose) {
+		// // Explicitly 'dispose' all created views
+		// List<MStack> stacks = new ArrayList<MStack>();
+		// gatherStacks(thePerspModel, stacks);
+		// for (Iterator iterator = stacks.iterator(); iterator
+		// .hasNext();) {
+		// MStack mStack = (MStack) iterator.next();
+		// String policy = mStack.getPolicy();
+		// if (policy == null)
+		// continue;
+		//						if (policy.indexOf("ViewStack") >= 0) { //$NON-NLS-1$
+		// EList<MItemPart<?>> vsKids = mStack.getChildren();
+		// for (Iterator iterator2 = vsKids.iterator(); iterator2
+		// .hasNext();) {
+		// MContributedPart<MPart<?>> view = (MContributedPart<MPart<?>>)
+		// iterator2
+		// .next();
+		// if (view.getObject() instanceof IViewPart) {
+		// Control ctrl = (Control) view.getWidget();
+		// if (ctrl.getMenu() != null)
+		// ctrl.setMenu(null);
+		// IViewPart vp = (IViewPart) view.getObject();
+		// vp.dispose();
+		// }
+		// }
+		// }
+		// }
+		// page.closePerspective(theDesc, true, false);
+		// }
+		// return okToClose;
+		// }
+		// };
+		//		perspContext.set("canCloseFunc", closeFunc); //$NON-NLS-1$
+		perspContext.set(Perspective.class.getName(), this);
+
+		// Always show the progress view since we don't have progress trim yet
+		MPart prgViewPart = ModeledPageLayout.findPart(perspModel,
+				"org.eclipse.ui.views.ProgressView"); //$NON-NLS-1$
+		if (prgViewPart != null) {
+			prgViewPart.setVisible(true);
+		}
+		// prgViewPart.getParent().setActiveChild(prgViewPart);
+		//showView("org.eclipse.ui.views.ProgressView", null); //$NON-NLS-1$
+	}
+
+	/**
+	 * @param e4Window
+	 */
+	private void createLegacyWBModel(MWindow e4Window) {
+		// MTrimStructure<MUIElement> trim = MApplicationFactory.eINSTANCE
+		// .createTrimStructure();
+
+		// Add a 'stickyRight' stack and populate it
+		MViewSashContainer mainSash = MApplicationFactory.eINSTANCE
+				.createViewSashContainer();
+		mainSash.setHorizontal(true);
+
+		MPerspectiveStack perspStack = MApplicationFactory.eINSTANCE
+				.createPerspectiveStack();
+		perspStack.setId("PerspectiveStack"); //$NON-NLS-1$
+
+		mainSash.getChildren().add(perspStack);
+
+		MViewStack stickyRight = MApplicationFactory.eINSTANCE
+				.createViewStack();
+		stickyRight.setId("stickyRight"); //$NON-NLS-1$
+		stickyRight.setVisible(false);
+		IStickyViewDescriptor[] descs = WorkbenchPlugin.getDefault()
+				.getViewRegistry().getStickyViews();
+		for (int i = 0; i < descs.length; i++) {
+			IStickyViewDescriptor stickyViewDescriptor = descs[i];
+			String id = stickyViewDescriptor.getId();
+			switch (stickyViewDescriptor.getLocation()) {
+			case IPageLayout.RIGHT:
+				MView view = ModeledPageLayout.createViewModel(id, false);
+				stickyRight.getChildren().add(view);
+				break;
+			}
+		}
+		mainSash.getChildren().add(stickyRight);
+		// trim.getChildren().add(mainSash);
+		e4Window.getChildren().add(mainSash);
+	}
+
+	private void loadExtensions(MPerspective perspModel,
+			ModeledPageLayout layout) {
+		String perspId = perspModel.getId();
+		if (perspId == null)
+			return;
+
+		IConfigurationElement[] perspExts = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_PERSPECTIVE_EXTENSIONS);
+		for (int i = 0; i < perspExts.length; i++) {
+			String extTarget = perspExts[i]
+					.getAttribute(IWorkbenchRegistryConstants.ATT_TARGET_ID);
+			if (perspId.equals(extTarget)) {
+				IConfigurationElement[] viewExts = perspExts[i]
+						.getChildren(IWorkbenchRegistryConstants.TAG_VIEW);
+				for (int j = 0; j < viewExts.length; j++) {
+					if (viewExts[j] == null)
+						continue; // this view has already being created
+					addView(j, viewExts, perspModel);
+				}
+			}
+		}
+	}
+
+	private MPart addView(int position, IConfigurationElement[] viewExts,
+			MPerspective perspModel) {
+		String id = viewExts[position]
+				.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+		// String relationship =
+		// viewExts[j].getAttribute("relationship");
+		String relative = viewExts[position]
+				.getAttribute(IWorkbenchRegistryConstants.ATT_RELATIVE);
+		String visible = viewExts[position]
+				.getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE);
+		// String closeable = viewExts[j].getAttribute("closeable");
+		// String showTitle = viewExts[j].getAttribute("showTitle");
+
+		MPart relPart = ModeledPageLayout.findPart(perspModel, relative);
+		if (relPart == null) { // is it declared later in the extensions?
+			for (int i = position + 1; i < viewExts.length; i++) {
+				if (viewExts[i] == null)
+					continue; // this view has already being created
+				String otherID = viewExts[i]
+						.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+				if (otherID == null)
+					continue;
+				if (otherID.equals(relative)) {
+					relPart = addView(i, viewExts, perspModel);
+					if (relPart != null)
+						break;
+				}
+			}
+		}
+		MViewStack sm;
+		if (relPart instanceof MView) {
+			MUIElement rp = relPart.getParent();
+			sm = (MViewStack) rp;
+		} else { // get a default stack
+			sm = getDefaultStack(perspModel);
+		}
+
+		MView viewModel = ModeledPageLayout.createViewModel(id, Boolean
+				.parseBoolean(visible));
+		sm.getChildren().add(viewModel);
+		viewExts[position] = null; // only create once
+		return viewModel;
+	}
+
+	private MViewStack getDefaultStack(MElementContainer<?> container) {
+		// TBD is there a better approach in 3.x?
+		// find any stack in the perspective's ascendants
+		for (MUIElement child : container.getChildren()) {
+			if (child instanceof MViewStack)
+				return (MViewStack) child;
+			if (child instanceof MElementContainer<?>) {
+				MViewStack result = getDefaultStack((MElementContainer<?>) child);
+				if (result != null)
+					return result;
+			}
+		}
+		return null;
+	}
+
+	private void removeAlwaysOn(IActionSetDescriptor descriptor) {
+		if (descriptor == null) {
+			return;
+		}
+		if (!alwaysOnActionSets.contains(descriptor)) {
+			return;
+		}
+
+		alwaysOnActionSets.remove(descriptor);
+		if (page != null) {
+			page.perspectiveActionSetChanged(this, descriptor,
+					ActionSetManager.CHANGE_HIDE);
+		}
+	}
+
+	protected void addAlwaysOff(IActionSetDescriptor descriptor) {
+		if (descriptor == null) {
+			return;
+		}
+		if (alwaysOffActionSets.contains(descriptor)) {
+			return;
+		}
+		alwaysOffActionSets.add(descriptor);
+		if (page != null) {
+			page.perspectiveActionSetChanged(this, descriptor,
+					ActionSetManager.CHANGE_MASK);
+		}
+		removeAlwaysOn(descriptor);
+	}
+
+	protected void addAlwaysOn(IActionSetDescriptor descriptor) {
+		if (descriptor == null) {
+			return;
+		}
+		if (alwaysOnActionSets.contains(descriptor)) {
+			return;
+		}
+		alwaysOnActionSets.add(descriptor);
+		if (page != null) {
+			page.perspectiveActionSetChanged(this, descriptor,
+					ActionSetManager.CHANGE_SHOW);
+		}
+		removeAlwaysOff(descriptor);
+	}
+
+	private void removeAlwaysOff(IActionSetDescriptor descriptor) {
+		if (descriptor == null) {
+			return;
+		}
+		if (!alwaysOffActionSets.contains(descriptor)) {
+			return;
+		}
+		alwaysOffActionSets.remove(descriptor);
+		if (page != null) {
+			page.perspectiveActionSetChanged(this, descriptor,
+					ActionSetManager.CHANGE_UNMASK);
+		}
+	}
+
+	/**
+	 * activate.
+	 */
+	protected void onActivate() {
+		// Update editor area state.
+
+	}
+
+	/**
+	 * deactivate.
+	 */
+	protected void onDeactivate() {
+		presentation.deactivate();
+		setActiveFastView(null);
+		setAllPinsVisible(false);
+
+		// Update fast views.
+		if (fastViewManager != null) {
+			List fastViews = fastViewManager.getFastViews(null);
+			for (int i = 0; i < fastViews.size(); i++) {
+				ViewPane pane = getPane((IViewReference) fastViews.get(i));
+				if (pane != null) {
+					Control ctrl = pane.getControl();
+					if (ctrl != null) {
+						ctrl.setEnabled(true); // Add focus support.
+					}
+				}
+			}
+
+			fastViewManager.deActivate();
+		}
+
+		// Ensure that the editor area trim is hidden as well
+		setEditorAreaTrimVisibility(false);
+	}
+
+	/**
+	 * Notifies that a part has been activated.
+	 */
+	public void partActivated(IWorkbenchPart activePart) {
+		// If a fastview is open close it.
+		if (activeFastView != null
+				&& activeFastView.getPart(false) != activePart) {
+			setActiveFastView(null);
+		}
+	}
+
+	/**
+	 * The user successfully performed a Show In... action on the specified
+	 * part. Update the history.
+	 */
+	public void performedShowIn(String partId) {
+		showInTimes.put(partId, new Long(System.currentTimeMillis()));
+	}
+
+	/**
+	 * Sets the fast view attribute. Note: The page is expected to update action
+	 * bars.
+	 */
+	public void removeFastView(IViewReference ref) {
+		removeFastView(ref, true);
+	}
+
+	/**
+	 * Sets the fast view attribute. Note: The page is expected to update action
+	 * bars.
+	 */
+	public void removeFastView(IViewReference ref, boolean handleLayout) {
+		ViewPane pane = getPane(ref);
+
+		if (activeFastView == ref) {
+			setActiveFastView(null);
+		}
+
+		pane.setFast(false);
+		Control ctrl = pane.getControl();
+		if (ctrl != null) {
+			ctrl.setEnabled(true); // Modify focus support.
+		}
+
+		if (handleLayout) {
+			// We are disabling the pane because it will be enabled when it
+			// is added to the presentation. When a pane is enabled a drop
+			// listener is added to it, and we do not want to have multiple
+			// listeners for a pane
+			presentation.addPart(pane);
+		}
+	}
+
+	/**
+	 * Fills a presentation with layout data. Note: This method should not
+	 * modify the current state of the perspective.
+	 */
+	public IStatus restoreState(IMemento memento) {
+		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+				WorkbenchMessages.Perspective_problemsRestoringPerspective,
+				null);
+
+		// Create persp descriptor.
+		descriptor = new PerspectiveDescriptor(null, null, null);
+		result.add(descriptor.restoreState(memento));
+		PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
+				.getDefault().getPerspectiveRegistry().findPerspectiveWithId(
+						descriptor.getId());
+		if (desc != null) {
+			descriptor = desc;
+		}
+
+		this.memento = memento;
+		// Add the visible views.
+		IMemento views[] = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+		result.merge(createReferences(views));
+
+		memento = memento.getChild(IWorkbenchConstants.TAG_FAST_VIEWS);
+		if (memento != null) {
+			views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+			result.merge(createReferences(views));
+		}
+		return result;
+	}
+
+	IStatus createReferences(IMemento views[]) {
+		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+				WorkbenchMessages.Perspective_problemsRestoringViews, null);
+
+		for (int x = 0; x < views.length; x++) {
+			// Get the view details.
+			IMemento childMem = views[x];
+			String id = childMem.getString(IWorkbenchConstants.TAG_ID);
+			// skip creation of the intro reference - it's handled elsewhere.
+			if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
+				continue;
+			}
+
+			String secondaryId = ViewFactory.extractSecondaryId(id);
+			if (secondaryId != null) {
+				id = ViewFactory.extractPrimaryId(id);
+			}
+			// Create and open the view.
+			try {
+				if (!"true".equals(childMem.getString(IWorkbenchConstants.TAG_REMOVED))) { //$NON-NLS-1$
+					viewFactory.createView(id, secondaryId);
+				}
+			} catch (PartInitException e) {
+				childMem.putString(IWorkbenchConstants.TAG_REMOVED, "true"); //$NON-NLS-1$
+				result.add(StatusUtil.newStatus(IStatus.ERROR,
+						e.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$
+						e));
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Fills a presentation with layout data. Note: This method should not
+	 * modify the current state of the perspective.
+	 */
+	public IStatus restoreState() {
+		if (this.memento == null) {
+			return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
+		}
+
+		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+				WorkbenchMessages.Perspective_problemsRestoringPerspective,
+				null);
+
+		IMemento memento = this.memento;
+		this.memento = null;
+
+		final IMemento boundsMem = memento
+				.getChild(IWorkbenchConstants.TAG_WINDOW);
+		if (boundsMem != null) {
+			final Rectangle r = new Rectangle(0, 0, 0, 0);
+			r.x = boundsMem.getInteger(IWorkbenchConstants.TAG_X).intValue();
+			r.y = boundsMem.getInteger(IWorkbenchConstants.TAG_Y).intValue();
+			r.height = boundsMem.getInteger(IWorkbenchConstants.TAG_HEIGHT)
+					.intValue();
+			r.width = boundsMem.getInteger(IWorkbenchConstants.TAG_WIDTH)
+					.intValue();
+			StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+				public void runWithException() throws Throwable {
+					if (page.getWorkbenchWindow().getPages().length == 0) {
+						page.getWorkbenchWindow().getShell().setBounds(r);
+					}
+				}
+			});
+
+		}
+
+		// Create an empty presentation..
+		final PerspectiveHelper[] presArray = new PerspectiveHelper[1];
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() throws Throwable {
+				ViewSashContainer mainLayout = new ViewSashContainer(page,
+						getClientComposite());
+				presArray[0] = new PerspectiveHelper(page, mainLayout,
+						Perspective.this);
+			}
+		});
+		final PerspectiveHelper pres = presArray[0];
+
+		// Read the layout.
+		result.merge(pres.restoreState(memento
+				.getChild(IWorkbenchConstants.TAG_LAYOUT)));
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() throws Throwable {
+				// Add the editor workbook. Do not hide it now.
+				pres.replacePlaceholderWithPart(editorArea);
+			}
+		});
+
+		// Add the visible views.
+		IMemento[] views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+
+		for (int x = 0; x < views.length; x++) {
+			// Get the view details.
+			IMemento childMem = views[x];
+			String id = childMem.getString(IWorkbenchConstants.TAG_ID);
+			String secondaryId = ViewFactory.extractSecondaryId(id);
+			if (secondaryId != null) {
+				id = ViewFactory.extractPrimaryId(id);
+			}
+
+			// skip the intro as it is restored higher up in workbench.
+			if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
+				continue;
+			}
+
+			// Create and open the view.
+			IViewReference viewRef = viewFactory.getView(id, secondaryId);
+			WorkbenchPartReference ref = (WorkbenchPartReference) viewRef;
+
+			// report error
+			if (ref == null) {
+				String key = ViewFactory.getKey(id, secondaryId);
+				result.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+						NLS.bind(WorkbenchMessages.Perspective_couldNotFind,
+								key), null));
+				continue;
+			}
+			boolean willPartBeVisible = pres.willPartBeVisible(ref.getId(),
+					secondaryId);
+			if (willPartBeVisible) {
+				IViewPart view = (IViewPart) ref.getPart(true);
+				if (view != null) {
+					ViewSite site = (ViewSite) view.getSite();
+					ViewPane pane = (ViewPane) site.getPane();
+					pres.replacePlaceholderWithPart(pane);
+				}
+			} else {
+				pres.replacePlaceholderWithPart(ref.getPane());
+			}
+		}
+
+		// Load the fast views
+		if (fastViewManager != null)
+			fastViewManager.restoreState(memento, result);
+
+		// Load the view layout recs
+		IMemento[] recMementos = memento
+				.getChildren(IWorkbenchConstants.TAG_VIEW_LAYOUT_REC);
+		for (int i = 0; i < recMementos.length; i++) {
+			IMemento recMemento = recMementos[i];
+			String compoundId = recMemento
+					.getString(IWorkbenchConstants.TAG_ID);
+			if (compoundId != null) {
+				ViewLayoutRec rec = getViewLayoutRec(compoundId, true);
+				if (IWorkbenchConstants.FALSE.equals(recMemento
+						.getString(IWorkbenchConstants.TAG_CLOSEABLE))) {
+					rec.isCloseable = false;
+				}
+				if (IWorkbenchConstants.FALSE.equals(recMemento
+						.getString(IWorkbenchConstants.TAG_MOVEABLE))) {
+					rec.isMoveable = false;
+				}
+				if (IWorkbenchConstants.TRUE.equals(recMemento
+						.getString(IWorkbenchConstants.TAG_STANDALONE))) {
+					rec.isStandalone = true;
+					rec.showTitle = !IWorkbenchConstants.FALSE
+							.equals(recMemento
+									.getString(IWorkbenchConstants.TAG_SHOW_TITLE));
+				}
+			}
+		}
+
+		final IContextService service = (IContextService) page
+				.getWorkbenchWindow().getService(IContextService.class);
+		try { // one big try block, don't kill me here
+			// defer context events
+			if (service != null) {
+				service.deferUpdates(true);
+			}
+
+			HashSet knownActionSetIds = new HashSet();
+
+			// Load the always on action sets.
+			IMemento[] actions = memento
+					.getChildren(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
+			for (int x = 0; x < actions.length; x++) {
+				String actionSetID = actions[x]
+						.getString(IWorkbenchConstants.TAG_ID);
+				final IActionSetDescriptor d = WorkbenchPlugin.getDefault()
+						.getActionSetRegistry().findActionSet(actionSetID);
+				if (d != null) {
+					StartupThreading
+							.runWithoutExceptions(new StartupRunnable() {
+								public void runWithException() throws Throwable {
+									addAlwaysOn(d);
+								}
+							});
+
+					knownActionSetIds.add(actionSetID);
+				}
+			}
+
+			// Load the always off action sets.
+			actions = memento
+					.getChildren(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
+			for (int x = 0; x < actions.length; x++) {
+				String actionSetID = actions[x]
+						.getString(IWorkbenchConstants.TAG_ID);
+				final IActionSetDescriptor d = WorkbenchPlugin.getDefault()
+						.getActionSetRegistry().findActionSet(actionSetID);
+				if (d != null) {
+					StartupThreading
+							.runWithoutExceptions(new StartupRunnable() {
+								public void runWithException() throws Throwable {
+									addAlwaysOff(d);
+								}
+							});
+					knownActionSetIds.add(actionSetID);
+				}
+			}
+
+			// Load "show view actions".
+			actions = memento
+					.getChildren(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
+			showViewShortcuts = new ArrayList(actions.length);
+			for (int x = 0; x < actions.length; x++) {
+				String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+				showViewShortcuts.add(id);
+			}
+
+			// Load "show in times".
+			actions = memento.getChildren(IWorkbenchConstants.TAG_SHOW_IN_TIME);
+			for (int x = 0; x < actions.length; x++) {
+				String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+				String timeStr = actions[x]
+						.getString(IWorkbenchConstants.TAG_TIME);
+				if (id != null && timeStr != null) {
+					try {
+						long time = Long.parseLong(timeStr);
+						showInTimes.put(id, new Long(time));
+					} catch (NumberFormatException e) {
+						// skip this one
+					}
+				}
+			}
+
+			// Load "show in parts" from registry, not memento
+			showInPartIds = getShowInIdsFromRegistry();
+
+			// Load "new wizard actions".
+			actions = memento
+					.getChildren(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
+			newWizardShortcuts = new ArrayList(actions.length);
+			for (int x = 0; x < actions.length; x++) {
+				String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+				newWizardShortcuts.add(id);
+			}
+
+			// Load "perspective actions".
+			actions = memento
+					.getChildren(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
+			perspectiveShortcuts = new ArrayList(actions.length);
+			for (int x = 0; x < actions.length; x++) {
+				String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+				perspectiveShortcuts.add(id);
+			}
+
+			// Load hidden menu item ids
+			actions = memento.getChildren(IWorkbenchConstants.TAG_HIDE_MENU);
+			hideMenuIDs = new HashSet();
+			for (int x = 0; x < actions.length; x++) {
+				String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+				hideMenuIDs.add(id);
+			}
+			actions = memento.getChildren(IWorkbenchConstants.TAG_HIDE_TOOLBAR);
+			hideToolBarIDs = new HashSet();
+			for (int x = 0; x < actions.length; x++) {
+				String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+				hideToolBarIDs.add(id);
+			}
+
+			ArrayList extActionSets = getPerspectiveExtensionActionSets();
+			for (int i = 0; i < extActionSets.size(); i++) {
+				String actionSetID = (String) extActionSets.get(i);
+				if (knownActionSetIds.contains(actionSetID)) {
+					continue;
+				}
+				final IActionSetDescriptor d = WorkbenchPlugin.getDefault()
+						.getActionSetRegistry().findActionSet(actionSetID);
+				if (d != null) {
+					StartupThreading
+							.runWithoutExceptions(new StartupRunnable() {
+								public void runWithException() throws Throwable {
+									addAlwaysOn(d);
+								}
+							});
+					knownActionSetIds.add(d.getId());
+				}
+			}
+
+			// Add the visible set of action sets to our knownActionSetIds
+			// Now go through the registry to ensure we pick up any new action
+			// sets
+			// that have been added but not yet considered by this perspective.
+			ActionSetRegistry reg = WorkbenchPlugin.getDefault()
+					.getActionSetRegistry();
+			IActionSetDescriptor[] array = reg.getActionSets();
+			int count = array.length;
+			for (int i = 0; i < count; i++) {
+				IActionSetDescriptor desc = array[i];
+				if ((!knownActionSetIds.contains(desc.getId()))
+						&& (desc.isInitiallyVisible())) {
+					addActionSet(desc);
+				}
+			}
+		} finally {
+			// restart context changes
+			if (service != null) {
+				StartupThreading.runWithoutExceptions(new StartupRunnable() {
+					public void runWithException() throws Throwable {
+						service.deferUpdates(false);
+					}
+				});
+			}
+		}
+
+		// Save presentation.
+		presentation = pres;
+
+		// Hide the editor area if needed. Need to wait for the
+		// presentation to be fully setup first.
+		Integer areaVisible = memento
+				.getInteger(IWorkbenchConstants.TAG_AREA_VISIBLE);
+		// Rather than hiding the editors now we must wait until after their
+		// controls
+		// are created. This ensures that if an editor is instantiated,
+		// createPartControl
+		// is also called. See bug 20166.
+		shouldHideEditorsOnActivate = (areaVisible != null && areaVisible
+				.intValue() == 0);
+
+		// Restore the trim state of the editor area
+		IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
+		boolean useNewMinMax = preferenceStore
+				.getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
+		if (useNewMinMax) {
+			Integer trimStateInt = memento
+					.getInteger(IWorkbenchConstants.TAG_AREA_TRIM_STATE);
+			if (trimStateInt != null) {
+				editorAreaState = trimStateInt.intValue() & 0x3; // low order
+				// two bits
+				// contain
+				// the state
+				editorAreaRestoreOnUnzoom = (trimStateInt.intValue() & 4) != 0;
+			}
+		}
+
+		// restore the fixed state
+		Integer isFixed = memento.getInteger(IWorkbenchConstants.TAG_FIXED);
+		fixed = (isFixed != null && isFixed.intValue() == 1);
+
+		return result;
+	}
+
+	/**
+	 * Restores a fast view to its corrent presentation structure. This method
+	 * is pubilc because the FastViewManager uses it to reconstruct it minimized
+	 * stacks on startup.
+	 * 
+	 * @param fvMemento
+	 *            The mement containing the fast view info
+	 * @param result
+	 *            The result status
+	 * @return The reference to the restored view
+	 */
+	public IViewReference restoreFastView(IMemento fvMemento, MultiStatus result) {
+		String viewID = fvMemento.getString(IWorkbenchConstants.TAG_ID);
+		String secondaryId = ViewFactory.extractSecondaryId(viewID);
+		if (secondaryId != null) {
+			viewID = ViewFactory.extractPrimaryId(viewID);
+		}
+
+		IViewReference viewRef = getViewFactory().getView(viewID, secondaryId);
+		if (viewRef == null) {
+			String key = ViewFactory.getKey(viewID, secondaryId);
+			WorkbenchPlugin.log("Could not create view: '" + key + "'."); //$NON-NLS-1$ //$NON-NLS-2$
+			result.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, NLS
+					.bind(WorkbenchMessages.Perspective_couldNotFind, key),
+					null));
+			return null;
+		}
+
+		// Restore fast view width ratio
+		Float ratio = fvMemento.getFloat(IWorkbenchConstants.TAG_RATIO);
+		if (ratio == null) {
+			Integer viewWidth = fvMemento
+					.getInteger(IWorkbenchConstants.TAG_WIDTH);
+			if (viewWidth == null) {
+				ratio = new Float(IPageLayout.DEFAULT_FASTVIEW_RATIO);
+			} else {
+				ratio = new Float((float) viewWidth.intValue()
+						/ (float) getClientComposite().getSize().x);
+			}
+		}
+		ViewLayoutRec rec = getViewLayoutRec(viewRef, true);
+		rec.fastViewWidthRatio = ratio.floatValue();
+
+		return viewRef;
+	}
+
+	/**
+	 * Returns the ActionSets read from perspectiveExtensions in the registry.
+	 */
+	protected ArrayList getPerspectiveExtensionActionSets() {
+		PerspectiveExtensionReader reader = new PerspectiveExtensionReader();
+		reader
+				.setIncludeOnlyTags(new String[] { IWorkbenchRegistryConstants.TAG_ACTION_SET });
+		PageLayout layout = new PageLayout();
+		reader.extendLayout(null, descriptor.getOriginalId(), layout);
+		return layout.getActionSets();
+	}
+
+	/**
+	 * Returns the Show In... part ids read from the registry.
+	 */
+	protected ArrayList getShowInIdsFromRegistry() {
+		PerspectiveExtensionReader reader = new PerspectiveExtensionReader();
+		reader
+				.setIncludeOnlyTags(new String[] { IWorkbenchRegistryConstants.TAG_SHOW_IN_PART });
+		PageLayout layout = new PageLayout();
+		reader.extendLayout(null, descriptor.getOriginalId(), layout);
+		return layout.getShowInPartIds();
+	}
+
+	/**
+	 * Save the layout.
+	 */
+	public void saveDesc() {
+		saveDescAs(descriptor);
+	}
+
+	/**
+	 * Save the layout.
+	 */
+	public void saveDescAs(IPerspectiveDescriptor desc) {
+		PerspectiveDescriptor realDesc = (PerspectiveDescriptor) desc;
+		// get the layout from the registry
+		PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
+				.getDefault().getPerspectiveRegistry();
+		// Capture the layout state.
+		XMLMemento memento = XMLMemento.createWriteRoot("perspective");//$NON-NLS-1$
+		IStatus status = saveState(memento, realDesc, false);
+		if (status.getSeverity() == IStatus.ERROR) {
+			ErrorDialog.openError((Shell) null,
+					WorkbenchMessages.Perspective_problemSavingTitle,
+					WorkbenchMessages.Perspective_problemSavingMessage, status);
+			return;
+		}
+		// save it to the preference store
+		try {
+			perspRegistry.saveCustomPersp(realDesc, memento);
+			descriptor = realDesc;
+		} catch (IOException e) {
+			perspRegistry.deletePerspective(realDesc);
+			MessageDialog.openError((Shell) null,
+					WorkbenchMessages.Perspective_problemSavingTitle,
+					WorkbenchMessages.Perspective_problemSavingMessage);
+		}
+	}
+
+	/**
+	 * Save the layout.
+	 */
+	public IStatus saveState(IMemento memento) {
+		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+				WorkbenchMessages.Perspective_problemsSavingPerspective, null);
+
+		result.merge(saveState(memento, descriptor, true));
+
+		return result;
+	}
+
+	/**
+	 * Save the layout.
+	 */
+	private IStatus saveState(IMemento memento, PerspectiveDescriptor p,
+			boolean saveInnerViewState) {
+		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+				WorkbenchMessages.Perspective_problemsSavingPerspective, null);
+
+		if (this.memento != null) {
+			memento.putMemento(this.memento);
+			return result;
+		}
+
+		// Save the version number.
+		memento.putString(IWorkbenchConstants.TAG_VERSION, VERSION_STRING);
+		result.add(p.saveState(memento));
+		if (!saveInnerViewState) {
+			Rectangle bounds = page.getWorkbenchWindow().getShell().getBounds();
+			IMemento boundsMem = memento
+					.createChild(IWorkbenchConstants.TAG_WINDOW);
+			boundsMem.putInteger(IWorkbenchConstants.TAG_X, bounds.x);
+			boundsMem.putInteger(IWorkbenchConstants.TAG_Y, bounds.y);
+			boundsMem.putInteger(IWorkbenchConstants.TAG_HEIGHT, bounds.height);
+			boundsMem.putInteger(IWorkbenchConstants.TAG_WIDTH, bounds.width);
+		}
+
+		// Save the "always on" action sets.
+		Iterator itr = alwaysOnActionSets.iterator();
+		while (itr.hasNext()) {
+			IActionSetDescriptor desc = (IActionSetDescriptor) itr.next();
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
+			child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
+		}
+
+		// Save the "always off" action sets.
+		itr = alwaysOffActionSets.iterator();
+		while (itr.hasNext()) {
+			IActionSetDescriptor desc = (IActionSetDescriptor) itr.next();
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
+			child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
+		}
+
+		// Save "show view actions"
+		itr = showViewShortcuts.iterator();
+		while (itr.hasNext()) {
+			String str = (String) itr.next();
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
+			child.putString(IWorkbenchConstants.TAG_ID, str);
+		}
+
+		// Save "show in times"
+		itr = showInTimes.keySet().iterator();
+		while (itr.hasNext()) {
+			String id = (String) itr.next();
+			Long time = (Long) showInTimes.get(id);
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_SHOW_IN_TIME);
+			child.putString(IWorkbenchConstants.TAG_ID, id);
+			child.putString(IWorkbenchConstants.TAG_TIME, time.toString());
+		}
+
+		// Save "new wizard actions".
+		itr = newWizardShortcuts.iterator();
+		while (itr.hasNext()) {
+			String str = (String) itr.next();
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
+			child.putString(IWorkbenchConstants.TAG_ID, str);
+		}
+
+		// Save "perspective actions".
+		itr = perspectiveShortcuts.iterator();
+		while (itr.hasNext()) {
+			String str = (String) itr.next();
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
+			child.putString(IWorkbenchConstants.TAG_ID, str);
+		}
+
+		// Save hidden menu item ids
+		itr = hideMenuIDs.iterator();
+		while (itr.hasNext()) {
+			String str = (String) itr.next();
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_HIDE_MENU);
+			child.putString(IWorkbenchConstants.TAG_ID, str);
+		}
+		itr = hideToolBarIDs.iterator();
+		while (itr.hasNext()) {
+			String str = (String) itr.next();
+			IMemento child = memento
+					.createChild(IWorkbenchConstants.TAG_HIDE_TOOLBAR);
+			child.putString(IWorkbenchConstants.TAG_ID, str);
+		}
+
+		// Get visible views.
+		List viewPanes = new ArrayList(5);
+		presentation.collectViewPanes(viewPanes);
+
+		// Save the views.
+		itr = viewPanes.iterator();
+		int errors = 0;
+		while (itr.hasNext()) {
+			ViewPane pane = (ViewPane) itr.next();
+			IViewReference ref = pane.getViewReference();
+			boolean restorable = page.getViewFactory().getViewRegistry().find(
+					ref.getId()).isRestorable();
+			if (restorable) {
+				IMemento viewMemento = memento
+						.createChild(IWorkbenchConstants.TAG_VIEW);
+				viewMemento.putString(IWorkbenchConstants.TAG_ID, ViewFactory
+						.getKey(ref));
+			}
+		}
+
+		// save all fastview state
+		if (fastViewManager != null)
+			fastViewManager.saveState(memento);
+
+		// Save the view layout recs.
+		for (Iterator i = mapIDtoViewLayoutRec.keySet().iterator(); i.hasNext();) {
+			String compoundId = (String) i.next();
+			ViewLayoutRec rec = (ViewLayoutRec) mapIDtoViewLayoutRec
+					.get(compoundId);
+			if (rec != null
+					&& (!rec.isCloseable || !rec.isMoveable || rec.isStandalone)) {
+				IMemento layoutMemento = memento
+						.createChild(IWorkbenchConstants.TAG_VIEW_LAYOUT_REC);
+				layoutMemento.putString(IWorkbenchConstants.TAG_ID, compoundId);
+				if (!rec.isCloseable) {
+					layoutMemento.putString(IWorkbenchConstants.TAG_CLOSEABLE,
+							IWorkbenchConstants.FALSE);
+				}
+				if (!rec.isMoveable) {
+					layoutMemento.putString(IWorkbenchConstants.TAG_MOVEABLE,
+							IWorkbenchConstants.FALSE);
+				}
+				if (rec.isStandalone) {
+					layoutMemento.putString(IWorkbenchConstants.TAG_STANDALONE,
+							IWorkbenchConstants.TRUE);
+					layoutMemento.putString(IWorkbenchConstants.TAG_SHOW_TITLE,
+							String.valueOf(rec.showTitle));
+				}
+			}
+		}
+
+		if (errors > 0) {
+			String message = WorkbenchMessages.Perspective_multipleErrors;
+			if (errors == 1) {
+				message = WorkbenchMessages.Perspective_oneError;
+			}
+			MessageDialog.openError(null, WorkbenchMessages.Error, message);
+		}
+
+		// Save the layout.
+		IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_LAYOUT);
+		result.add(presentation.saveState(childMem));
+
+		// Save the editor visibility state
+		if (isEditorAreaVisible()) {
+			memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 1);
+		} else {
+			memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 0);
+		}
+
+		// Save the trim state of the editor area if using the new min/max
+		IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
+		boolean useNewMinMax = preferenceStore
+				.getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
+		if (useNewMinMax) {
+			int trimState = editorAreaState;
+			trimState |= editorAreaRestoreOnUnzoom ? 4 : 0;
+			memento.putInteger(IWorkbenchConstants.TAG_AREA_TRIM_STATE,
+					trimState);
+		}
+
+		// Save the fixed state
+		if (fixed) {
+			memento.putInteger(IWorkbenchConstants.TAG_FIXED, 1);
+		} else {
+			memento.putInteger(IWorkbenchConstants.TAG_FIXED, 0);
+		}
+
+		return result;
+	}
+
+	public void turnOnActionSets(IActionSetDescriptor[] newArray) {
+		for (int i = 0; i < newArray.length; i++) {
+			IActionSetDescriptor descriptor = newArray[i];
+
+			addAlwaysOn(descriptor);
+		}
+	}
+
+	public void turnOffActionSets(IActionSetDescriptor[] toDisable) {
+		for (int i = 0; i < toDisable.length; i++) {
+			IActionSetDescriptor descriptor = toDisable[i];
+
+			turnOffActionSet(descriptor);
+		}
+	}
+
+	public void turnOffActionSet(IActionSetDescriptor toDisable) {
+		addAlwaysOff(toDisable);
+	}
+
+	/**
+	 * Return the active fast view or null if there are no fast views or if
+	 * there are all minimized.
+	 */
+	public IViewReference getActiveFastView() {
+		return activeFastView;
+	}
+
+	/**
+	 * Sets the active fast view. If a different fast view is already open, it
+	 * shrinks equally <code>steps</code> times before disappearing completely.
+	 * Then, <code>view</code> becomes active and is shown.
+	 */
+	/* package */void setActiveFastView(IViewReference ref, int steps) {
+		if (activeFastView == ref) {
+			return;
+		}
+
+		if (activeFastView != null) {
+			ViewPane pane = getPane(activeFastView);
+			if (pane != null) {
+				if (pane.isZoomed()) {
+					presentation.zoomOut();
+				}
+				hideFastView(activeFastView, steps);
+			}
+		}
+		activeFastView = ref;
+		try {
+			if (activeFastView != null) {
+				if (!showFastView(activeFastView)) {
+					activeFastView = null;
+				}
+			}
+		} catch (RuntimeException e) {
+			activeFastView = null;
+		}
+	}
+
+	/**
+	 * Sets the active fast view.
+	 */
+	/* package */void setActiveFastView(IViewReference ref) {
+		setActiveFastView(ref, FASTVIEW_HIDE_STEPS);
+	}
+
+	/**
+	 * Sets the visibility of all fast view pins.
+	 */
+	protected void setAllPinsVisible(boolean visible) {
+		if (fastViewManager == null)
+			return;
+
+		Iterator iter = fastViewManager.getFastViews(null).iterator();
+		while (iter.hasNext()) {
+			ViewPane pane = getPane((IViewReference) iter.next());
+			if (pane != null) {
+				pane.setFast(visible);
+			}
+		}
+	}
+
+	/**
+	 * Sets the selection for the shortcut bar icon representing the givevn fast
+	 * view.
+	 */
+	private void setFastViewIconSelection(IViewReference ref, boolean selected) {
+		if (fastViewManager == null)
+			return;
+
+		fastViewManager.setFastViewIconSelection(ref, selected);
+	}
+
+	/**
+	 * Sets the new wizard actions for the page. This is List of Strings.
+	 */
+	public void setNewWizardActionIds(ArrayList newList) {
+		newWizardShortcuts = newList;
+	}
+
+	/**
+	 * Sets the perspective actions for this page. This is List of Strings.
+	 */
+	public void setPerspectiveActionIds(ArrayList list) {
+		perspectiveShortcuts = list;
+	}
+
+	/**
+	 * Sets the ids of the parts to list in the Show In... prompter. This is a
+	 * List of Strings.
+	 */
+	public void setShowInPartIds(ArrayList list) {
+		showInPartIds = list;
+	}
+
+	/**
+	 * Sets the ids of the views to list in the Show View shortcuts. This is a
+	 * List of Strings.
+	 */
+	public void setShowViewActionIds(ArrayList list) {
+		showViewShortcuts = list;
+	}
+
+	/**
+	 * Show the editor area if not visible
+	 */
+	protected void showEditorArea() {
+		if (isEditorAreaVisible()) {
+			return;
+		}
+
+		editorHidden = false;
+
+		// Show the editor in the appropriate location
+		if (useNewMinMax(this)) {
+			boolean isMinimized = editorAreaState == IStackPresentationSite.STATE_MINIMIZED;
+			if (!isMinimized) {
+				// If the editor area is going to show then we have to restore
+				if (getPresentation().getMaximizedStack() != null)
+					getPresentation().getMaximizedStack().setState(
+							IStackPresentationSite.STATE_RESTORED);
+
+				showEditorAreaLocal();
+			} else
+				setEditorAreaTrimVisibility(true);
+		} else {
+			showEditorAreaLocal();
+		}
+	}
+
+	/**
+	 * Show the editor area if not visible
+	 */
+	protected void showEditorAreaLocal() {
+		if (editorHolder == null || editorHidden) {
+			return;
+		}
+
+		// Replace the part holder with the editor area.
+		presentation.getLayout().replace(editorHolder, editorArea);
+		editorHolder = null;
+	}
+
+	private EditorAreaTrimToolBar getEditorAreaTrim(boolean createIfNecessary) {
+		WorkbenchWindow wbw = (WorkbenchWindow) page.getWorkbenchWindow();
+		ITrimManager tbm = wbw.getTrimManager();
+		if (tbm == null)
+			return null;
+
+		// Create if necesary
+		EditorAreaTrimToolBar editorAreaTrim = (EditorAreaTrimToolBar) tbm
+				.getTrim(IPageLayout.ID_EDITOR_AREA);
+		if (editorAreaTrim == null && createIfNecessary) {
+			int suggestedSide = SWT.RIGHT;
+			int cachedSide = ((TrimLayout) tbm)
+					.getPreferredArea(IPageLayout.ID_EDITOR_AREA);
+			if (cachedSide != -1)
+				suggestedSide = cachedSide;
+
+			IWindowTrim beforeMe = ((TrimLayout) tbm)
+					.getPreferredLocation(IPageLayout.ID_EDITOR_AREA);
+
+			// Gain access to the trim manager
+			editorAreaTrim = new EditorAreaTrimToolBar(wbw, editorArea);
+			editorAreaTrim.dock(suggestedSide);
+			tbm.addTrim(suggestedSide, editorAreaTrim, beforeMe);
+		}
+
+		return editorAreaTrim;
+	}
+
+	public void setEditorAreaState(int newState) {
+		if (newState == editorAreaState)
+			return;
+
+		editorAreaState = newState;
+
+		// reset the restore flag if we're not minimized
+		if (newState != IStackPresentationSite.STATE_MINIMIZED)
+			editorAreaRestoreOnUnzoom = false;
+
+		refreshEditorAreaVisibility();
+	}
+
+	public int getEditorAreaState() {
+		return editorAreaState;
+	}
+
+	/**
+	 * 
+	 */
+	public void refreshEditorAreaVisibility() {
+		// Nothing shows up if the editor area isn't visible at all
+		if (editorHidden) {
+			hideEditorAreaLocal();
+			setEditorAreaTrimVisibility(false);
+			return;
+		}
+
+		EditorStack editorStack = ((EditorSashContainer) editorArea)
+				.getUpperRightEditorStack(null);
+		if (editorStack == null)
+			return;
+
+		// Whatever we're doing, make the current editor stack match it
+		editorStack.setStateLocal(editorAreaState);
+
+		// If it's minimized then it's in the trim
+		if (editorAreaState == IStackPresentationSite.STATE_MINIMIZED) {
+			// Hide the editor area and show its trim
+			hideEditorAreaLocal();
+			setEditorAreaTrimVisibility(true);
+		} else {
+			// Show the editor area and hide its trim
+			setEditorAreaTrimVisibility(false);
+			showEditorAreaLocal();
+
+			if (editorAreaState == IStackPresentationSite.STATE_MAXIMIZED)
+				getPresentation().setMaximizedStack(editorStack);
+		}
+	}
+
+	protected EditorAreaTrimToolBar setEditorAreaTrimVisibility(boolean visible) {
+		WorkbenchWindow wbw = (WorkbenchWindow) page.getWorkbenchWindow();
+		ITrimManager tbm = wbw.getTrimManager();
+		if (tbm == null)
+			return null;
+
+		// Only create the trim element if it's going to be visible
+		EditorAreaTrimToolBar editorAreaTrim = getEditorAreaTrim(visible);
+		if (editorAreaTrim == null)
+			return null;
+
+		tbm.setTrimVisible(editorAreaTrim, visible);
+		tbm.forceLayout();
+
+		return editorAreaTrim;
+	}
+
+	/**
+	 * Shows a fast view.
+	 * 
+	 * @return whether the view was successfully shown
+	 */
+	boolean showFastView(IViewReference ref) {
+		if (fastViewManager == null)
+			return false;
+
+		// Make sure the part is restored.
+		IWorkbenchPart refPart = ref.getPart(true);
+		if (refPart == null) {
+			return false;
+		}
+
+		ViewPane pane = getPane(ref);
+		if (pane == null) {
+			return false;
+		}
+
+		saveFastViewWidthRatio();
+
+		// Special check to ensure that a 'minimized' intro view shows
+		// as 'standby'
+		if (ref.getId().equals("org.eclipse.ui.internal.introview")) { //$NON-NLS-1$
+			if (refPart instanceof ViewIntroAdapterPart) {
+				((ViewIntroAdapterPart) refPart).setStandby(true);
+			}
+		}
+
+		// Determine the display orientation
+		int side = fastViewManager.getViewSide(ref);
+		fastViewPane.showView(getClientComposite(), pane, side,
+				getFastViewWidthRatio(ref));
+
+		setFastViewIconSelection(ref, true);
+
+		return true;
+	}
+
+	private void saveFastViewWidthRatio() {
+		ViewPane pane = fastViewPane.getCurrentPane();
+		if (pane != null) {
+			ViewLayoutRec rec = getViewLayoutRec(pane.getViewReference(), true);
+			rec.fastViewWidthRatio = fastViewPane.getCurrentRatio();
+		}
+	}
+
+	/**
+	 * Resolves a view's id into its reference, creating the view if necessary.
+	 * 
+	 * @param viewId
+	 *            The primary id of the view (must not be <code>null</code>
+	 * @param secondaryId
+	 *            The secondary id of a multiple-instance view (may be
+	 *            <code>null</code>).
+	 * 
+	 * @return The reference to the specified view. This may be null if the view
+	 *         fails to create (i.e. thrown a PartInitException)
+	 */
+	public IViewReference getViewReference(String viewId, String secondaryId) {
+		IViewReference ref = page.findViewReference(viewId, secondaryId);
+		if (ref == null) {
+			ViewFactory factory = getViewFactory();
+			try {
+				ref = factory.createView(viewId, secondaryId);
+			} catch (PartInitException e) {
+				IStatus status = StatusUtil.newStatus(IStatus.ERROR, e
+						.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$
+						e);
+				StatusUtil.handleStatus(status,
+						"Failed to create view: id=" + viewId, //$NON-NLS-1$
+						StatusManager.LOG);
+			}
+		}
+		return ref;
+	}
+
+	private MElementContainer<MUIElement> findBottomStack(MPerspective persp) {
+		List stacks = new ArrayList();
+		gatherStacks(persp, stacks);
+		if (stacks.size() > 0)
+			return (MElementContainer<MUIElement>) stacks
+					.get(stacks.size() - 1);
+		return null;
+	}
+
+	/**
+	 * @param persp
+	 * @param stacks
+	 */
+	private void gatherStacks(MElementContainer<? extends MUIElement> persp,
+			List stacks) {
+		for (MUIElement kid : persp.getChildren()) {
+			if (kid instanceof ViewStack) {
+				stacks.add(kid);
+			}
+			if (kid instanceof MElementContainer<?>)
+				gatherStacks((MElementContainer<? extends MUIElement>) kid,
+						stacks);
+		}
+	}
+
+	/**
+	 * Shows the view with the given id and secondary id.
+	 */
+	public IViewPart showView(String viewId, String secondaryId)
+			throws PartInitException {
+		// Is it already there?
+		MWindow e4Window = page.getModelWindow();
+		MPerspectiveStack perspStack = (MPerspectiveStack) ModeledPageLayout
+				.findElementById(e4Window, "PerspectiveStack"); //$NON-NLS-1$
+		final MPerspective perspectiveModel = (MPerspective) perspStack
+				.getActiveChild();
+		MView view = (MView) ModeledPageLayout.findPart(perspectiveModel,
+				viewId);
+
+		// also check 'stickyRight' since it's not in a perspective
+		if (view == null) {
+			ViewStack stickyRight = (ViewStack) ModeledPageLayout
+					.findElementById(e4Window, "stickyRight"); //$NON-NLS-1$
+			view = (MView) ModeledPageLayout.findElementById(
+					(MUIElement) stickyRight, viewId);
+		}
+		boolean doLayout = false;
+
+		// if not, add it
+		MElementContainer<MUIElement> theStack = null;
+		if (view == null) {
+			// Place it in the 'bottom' stack
+			theStack = (MElementContainer<MUIElement>) ModeledPageLayout
+					.findElementById(perspectiveModel, "bottom"); //$NON-NLS-1$
+			if (theStack == null)
+				theStack = findBottomStack(perspectiveModel);
+
+			// If the stack is hidden, show it
+			if (!theStack.isVisible()) {
+				theStack.setVisible(true);
+				doLayout = true;
+			}
+
+			view = ModeledPageLayout.createViewModel(viewId, true);
+			theStack.getChildren().add(view);
+		} else {
+			// Its stack is where it already is
+			theStack = view.getParent();
+
+			// If the stack is hidden, show it
+			if (!theStack.isVisible()) {
+				theStack.setVisible(true);
+				doLayout = true;
+			}
+
+			// create it if necessary
+			if (!view.isVisible()) {
+				// Move it to the end of the stack
+				theStack.getChildren().remove(view);
+				theStack.getChildren().add(view);
+				view.setVisible(true);
+			}
+		}
+
+		if (doLayout && theStack.getParent().getWidget() instanceof Composite) {
+			Composite comp = (Composite) theStack.getParent().getWidget();
+			comp.layout(true);
+		}
+
+		// OK, make it active
+		theStack.setActiveChild(view);
+
+		LegacyView lView = (LegacyView) view.getObject();
+		return lView != null ? lView.getViewPart() : null;
+	}
+
+	/**
+	 * Toggles the visibility of a fast view. If the view is active it is
+	 * deactivated. Otherwise, it is activated.
+	 */
+	public void toggleFastView(IViewReference ref) {
+		if (ref == activeFastView) {
+			setActiveFastView(null);
+		} else {
+			setActiveFastView(ref);
+		}
+	}
+
+	/**
+	 * Returns the old part reference. Returns null if there was no previously
+	 * active part.
+	 * 
+	 * @return the old part reference or <code>null</code>
+	 */
+	public IWorkbenchPartReference getOldPartRef() {
+		return oldPartRef;
+	}
+
+	/**
+	 * Sets the old part reference.
+	 * 
+	 * @param oldPartRef
+	 *            The old part reference to set, or <code>null</code>
+	 */
+	public void setOldPartRef(IWorkbenchPartReference oldPartRef) {
+		this.oldPartRef = oldPartRef;
+	}
+
+	// for dynamic UI
+	protected void addActionSet(IActionSetDescriptor newDesc) {
+		IContextService service = (IContextService) page.getWorkbenchWindow()
+				.getService(IContextService.class);
+		try {
+			service.deferUpdates(true);
+			for (int i = 0; i < alwaysOnActionSets.size(); i++) {
+				IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOnActionSets
+						.get(i);
+				if (desc.getId().equals(newDesc.getId())) {
+					removeAlwaysOn(desc);
+					removeAlwaysOff(desc);
+					break;
+				}
+			}
+			addAlwaysOn(newDesc);
+		} finally {
+			service.deferUpdates(false);
+		}
+	}
+
+	// for dynamic UI
+	/* package */void removeActionSet(String id) {
+		IContextService service = (IContextService) page.getWorkbenchWindow()
+				.getService(IContextService.class);
+		try {
+			service.deferUpdates(true);
+			for (int i = 0; i < alwaysOnActionSets.size(); i++) {
+				IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOnActionSets
+						.get(i);
+				if (desc.getId().equals(id)) {
+					removeAlwaysOn(desc);
+					break;
+				}
+			}
+
+			for (int i = 0; i < alwaysOffActionSets.size(); i++) {
+				IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOffActionSets
+						.get(i);
+				if (desc.getId().equals(id)) {
+					removeAlwaysOff(desc);
+					break;
+				}
+			}
+		} finally {
+			service.deferUpdates(false);
+		}
+	}
+
+	void removeActionSet(IActionSetDescriptor toRemove) {
+		removeAlwaysOn(toRemove);
+		removeAlwaysOff(toRemove);
+	}
+
+	public void setFastViewState(int newState) {
+		fastViewPane.setState(newState);
+	}
+
+	public int getFastViewState() {
+		return fastViewPane.getState();
+	}
+
+	/**
+	 * Returns whether the given view is closeable in this perspective.
+	 * 
+	 * @since 3.0
+	 */
+	public boolean isCloseable(IViewReference reference) {
+		ViewLayoutRec rec = getViewLayoutRec(reference, false);
+		if (rec != null) {
+			return rec.isCloseable;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns whether the given view is moveable in this perspective.
+	 * 
+	 * @since 3.0
+	 */
+	public boolean isMoveable(IViewReference reference) {
+		ViewLayoutRec rec = getViewLayoutRec(reference, false);
+		if (rec != null) {
+			return rec.isMoveable;
+		}
+		return true;
+	}
+
+	/**
+	 * Writes a description of the layout to the given string buffer. This is
+	 * used for drag-drop test suites to determine if two layouts are the same.
+	 * Like a hash code, the description should compare as equal iff the layouts
+	 * are the same. However, it should be user-readable in order to help debug
+	 * failed tests. Although these are english readable strings, they should
+	 * not be translated or equality tests will fail.
+	 * <p>
+	 * This is only intended for use by test suites.
+	 * </p>
+	 * 
+	 * @param buf
+	 */
+	public void describeLayout(StringBuffer buf) {
+		IViewReference[] fastViews = getFastViews();
+
+		if (fastViews.length != 0) {
+			buf.append("fastviews ("); //$NON-NLS-1$
+			for (int idx = 0; idx < fastViews.length; idx++) {
+				IViewReference ref = fastViews[idx];
+
+				if (idx > 0) {
+					buf.append(", "); //$NON-NLS-1$
+				}
+
+				buf.append(ref.getPartName());
+			}
+			buf.append("), "); //$NON-NLS-1$
+		}
+
+		getPresentation().describeLayout(buf);
+	}
+
+	/**
+	 * Sanity-checks the LayoutParts in this perspective. Throws an Assertation
+	 * exception if an object's internal state is invalid.
+	 */
+	public void testInvariants() {
+		getPresentation().getLayout().testInvariants();
+	}
+
+	public IActionSetDescriptor[] getAlwaysOnActionSets() {
+		return (IActionSetDescriptor[]) alwaysOnActionSets
+				.toArray(new IActionSetDescriptor[alwaysOnActionSets.size()]);
+	}
+
+	public IActionSetDescriptor[] getAlwaysOffActionSets() {
+		return (IActionSetDescriptor[]) alwaysOffActionSets
+				.toArray(new IActionSetDescriptor[alwaysOffActionSets.size()]);
+	}
+
+	/* package */FastViewPane getFastViewPane() {
+		return fastViewPane;
+	}
+
+	/**
+	 * Restores a part in the trim to the actual layout
+	 * 
+	 * @param part
+	 *            The part to restore
+	 */
+	public void restoreTrimPart(LayoutPart part) {
+		if (fastViewManager == null)
+			return;
+
+		// Remove any current fastview
+		setActiveFastView(null);
+
+		// Set the part's state to place it back in the layout
+		if (part instanceof ViewStack) {
+			ViewStack vs = (ViewStack) part;
+			fastViewManager.restoreToPresentation(vs.getID());
+		}
+
+		if (part == editorArea) {
+			setEditorAreaState(IStackPresentationSite.STATE_RESTORED);
+			editorAreaRestoreOnUnzoom = false;
+		}
+	}
+
+	/**
+	 * Determine the correct side to initially dock a new trim part on. We do
+	 * this by checking its rect against the editor area.
+	 * 
+	 * @param stackBounds
+	 *            The bounds of the stack we want to create trim for
+	 * @return the SWT side to dock the trim element on
+	 */
+	public int calcStackSide(Rectangle stackBounds) {
+		// Where is the stack in relation to the EditorArea?
+		Rectangle editorAreaBounds = editorArea.getBounds();
+
+		// Is this the Editor Area
+		if (editorAreaBounds.equals(stackBounds))
+			return SWT.TOP;
+
+		Point stackCenter = Geometry.centerPoint(stackBounds);
+		Point editorAreaCenter = Geometry.centerPoint(editorAreaBounds);
+
+		int dx = editorAreaCenter.x - stackCenter.x;
+		int dy = editorAreaCenter.y - stackCenter.y;
+
+		if (Math.abs(dx) > Math.abs(dy)) {
+			return (dx > 0) ? SWT.LEFT : SWT.RIGHT;
+		}
+
+		if (dy > 0) {
+			return (dx > 0) ? SWT.LEFT : SWT.RIGHT;
+		}
+
+		return SWT.BOTTOM;
+	}
+
+	/**
+	 * Restore any parts that are showing in the trim as a result of a 'zoom'
+	 * operation
+	 */
+	public void restoreZoomedParts() {
+		if (fastViewManager == null)
+			return;
+
+		// Remove any current fastview
+		setActiveFastView(null);
+
+		// have the layout restore the parts
+		fastViewManager.restoreZoomedViewStacks();
+
+		if (editorAreaRestoreOnUnzoom) {
+			restoreTrimPart(editorArea);
+		}
+	}
+
+	/**
+	 * @return Returns the fastViewManager.
+	 */
+	public FastViewManager getFastViewManager() {
+		return fastViewManager;
+	}
+
+	/**
+	 * Sets the restore on unzoom state for the editor area
+	 * 
+	 * @param restore
+	 *            the new state
+	 */
+	public void setEditorAreaRestoreOnUnzoom(boolean restore) {
+		editorAreaRestoreOnUnzoom = restore;
+	}
+
+	/**
+	 * @return the restore on unzoom state
+	 */
+	public boolean getEditorAreaRestoreOnUnzoom() {
+		return editorAreaRestoreOnUnzoom;
+	}
+
+	/**
+	 * Used to restrict the use of the new min/max behavior to envoronments in
+	 * which it has a chance of working...
+	 * 
+	 * @param activePerspective
+	 *            We pass this in as an arg so others won't have to check it for
+	 *            'null' (which is one of the failure cases)
+	 * 
+	 */
+	public static boolean useNewMinMax(Perspective activePerspective) {
+		// We need to have an active perspective
+		if (activePerspective == null)
+			return false;
+
+		// We need to have a trim manager (if we don't then we
+		// don't create a FastViewManager because it'd be useless)
+		if (activePerspective.getFastViewManager() == null)
+			return false;
+
+		// Make sure we don't NPE anyplace
+		WorkbenchWindow wbw = (WorkbenchWindow) activePerspective.page
+				.getWorkbenchWindow();
+		if (wbw == null)
+			return false;
+
+		WorkbenchWindowConfigurer configurer = wbw.getWindowConfigurer();
+		if (configurer == null)
+			return false;
+
+		AbstractPresentationFactory factory = configurer
+				.getPresentationFactory();
+		if (factory == null)
+			return false;
+
+		// Ok, we should be good to go, return the pref
+		IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
+		boolean useNewMinMax = preferenceStore
+				.getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
+		return useNewMinMax;
+	}
+
+	/** @return a Collection of IDs of items to be hidden from the menu bar */
+	public Collection getHiddenMenuItems() {
+		return hideMenuIDs;
+	}
+
+	/** @return a Collection of IDs of items to be hidden from the tool bar */
+	public Collection getHiddenToolbarItems() {
+		return hideToolBarIDs;
+	}
+
+	public void updateActionBars() {
+		page.getActionBars().getMenuManager().updateAll(true);
+		page.resetToolBarLayout();
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewIntroAdapterPart.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewIntroAdapterPart.java
new file mode 100644
index 0000000..6b286ce
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewIntroAdapterPart.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.internal.intro.IntroMessages;
+import org.eclipse.ui.intro.IIntroPart;
+import org.eclipse.ui.intro.IIntroSite;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * Simple view that will wrap an <code>IIntroPart</code>.
+ * 
+ * e4: hacked to remove reference to
+ * WorkbenchPartReference.addInternalPropertyListener
+ * 
+ * @since 3.0
+ */
+public final class ViewIntroAdapterPart extends ViewPart {
+
+	private boolean handleZoomEvents = true;
+
+	private IIntroPart introPart;
+
+	private IIntroSite introSite;
+
+	private Composite parentControl;
+
+	/**
+	 * Adds a listener that toggles standby state if the view pane is zoomed.
+	 */
+	private void addPaneListener() {
+		// e4: switch from using internal property listener
+		parentControl.addControlListener(new ControlAdapter() {
+			boolean isInitialized = false;
+			boolean isStandby = false;
+
+			@Override
+			public void controlResized(ControlEvent e) {
+				if (handleZoomEvents) {
+					// put view in standby mode if smaller than a certain size
+					boolean newStandby = parentControl.getBounds().width < 600;
+					if (!isInitialized || newStandby != isStandby) {
+						isInitialized = true;
+						isStandby = newStandby;
+						setStandby(newStandby);
+					}
+				}
+			}
+		});
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets
+	 * .Composite)
+	 */
+	public void createPartControl(Composite parent) {
+		this.parentControl = parent;
+		addPaneListener();
+		introPart.createPartControl(parent);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
+	 */
+	public void dispose() {
+		setBarVisibility(true);
+		super.dispose();
+		getSite().getWorkbenchWindow().getWorkbench().getIntroManager()
+				.closeIntro(introPart);
+		introPart.dispose();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		return introPart.getAdapter(adapter);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.part.WorkbenchPart#getTitle()
+	 */
+	public String getTitle() {
+		// this method is called eagerly before our init method is called (and
+		// therefore before our intropart is created). By default return
+		// the view title from the view declaration. We will fire a property
+		// change to set the title to the proper value in the init method.
+		return introPart == null ? super.getTitle() : introPart.getTitle();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPart#getTitleImage()
+	 */
+	public Image getTitleImage() {
+		return introPart.getTitleImage();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite,
+	 * org.eclipse.ui.IMemento)
+	 */
+	public void init(IViewSite site, IMemento memento) throws PartInitException {
+		super.init(site);
+		Workbench workbench = (Workbench) site.getWorkbenchWindow()
+				.getWorkbench();
+		try {
+			introPart = workbench.getWorkbenchIntroManager()
+					.createNewIntroPart();
+			// reset the part name of this view to be that of the intro title
+			setPartName(introPart.getTitle());
+			introPart.addPropertyListener(new IPropertyListener() {
+				public void propertyChanged(Object source, int propId) {
+					firePropertyChange(propId);
+				}
+			});
+			introSite = new ViewIntroAdapterSite(site, workbench
+					.getIntroDescriptor());
+			introPart.init(introSite, memento);
+
+		} catch (CoreException e) {
+			WorkbenchPlugin.log(IntroMessages.Intro_could_not_create_proxy,
+					new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH,
+							IStatus.ERROR,
+							IntroMessages.Intro_could_not_create_proxy, e));
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
+	 */
+	public void saveState(IMemento memento) {
+		introPart.saveState(memento);
+	}
+
+	/**
+	 * Sets whether the CoolBar/PerspectiveBar should be visible.
+	 * 
+	 * @param visible
+	 *            whether the CoolBar/PerspectiveBar should be visible
+	 * @since 3.1
+	 */
+	private void setBarVisibility(final boolean visible) {
+		WorkbenchWindow window = (WorkbenchWindow) getSite()
+				.getWorkbenchWindow();
+
+		final boolean layout = (visible != window.getCoolBarVisible())
+				|| (visible != window.getPerspectiveBarVisible()); // don't
+		// layout unless things have actually changed
+		if (visible) {
+			window.setCoolBarVisible(true);
+			window.setPerspectiveBarVisible(true);
+		} else {
+			window.setCoolBarVisible(false);
+			window.setPerspectiveBarVisible(false);
+		}
+
+		if (layout) {
+			window.getShell().layout();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPart#setFocus()
+	 */
+	public void setFocus() {
+		introPart.setFocus();
+	}
+
+	/**
+	 * Toggles handling of zoom events.
+	 * 
+	 * @param handle
+	 *            whether to handle zoom events
+	 */
+	public void setHandleZoomEvents(boolean handle) {
+		handleZoomEvents = handle;
+	}
+
+	/**
+	 * Forces the standby state of the intro part.
+	 * 
+	 * @param standby
+	 *            update the standby state
+	 */
+	public void setStandby(final boolean standby) {
+		final Control control = parentControl;
+		if (control == null || control.isDisposed())
+			return;
+		BusyIndicator.showWhile(control.getDisplay(), new Runnable() {
+			public void run() {
+				try {
+					control.setRedraw(false);
+					introPart.standbyStateChanged(standby);
+				} finally {
+					control.setRedraw(true);
+				}
+
+				setBarVisibility(standby);
+			}
+		});
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java
new file mode 100644
index 0000000..3509af1
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.internal.provisional.action.ToolBarManager2;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.SubActionBars;
+
+/**
+ * A view container manages the services for a view.
+ */
+public class ViewSite extends PartSite implements IViewSite {
+
+	/**
+	 * @param ref
+	 * @param part
+	 * @param page
+	 */
+	public ViewSite(IViewReference ref, IWorkbenchPart part, IWorkbenchPage page) {
+		super(ref, part, page);
+		SubActionBars bars = new SubActionBars(((WorkbenchPage) page)
+				.getActionBars(), serviceLocator) {
+			private IToolBarManager tbMgr;
+			private MenuManager menuMgr;
+
+			@Override
+			public IToolBarManager getToolBarManager() {
+				if (tbMgr == null) {
+					tbMgr = new ToolBarManager2();
+				}
+				return tbMgr;
+			}
+
+			@Override
+			public IMenuManager getMenuManager() {
+				if (menuMgr == null) {
+					menuMgr = new MenuManager();
+				}
+				return menuMgr;
+			}
+		};
+		setActionBars(bars);
+	}
+
+	/**
+	 * Returns the secondary id or <code>null</code>.
+	 */
+	public String getSecondaryId() {
+		return ((IViewReference) getPartReference()).getSecondaryId();
+	}
+
+	/**
+	 * Returns the view.
+	 */
+	public IViewPart getViewPart() {
+		return (IViewPart) getPart();
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Workbench.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Workbench.java
new file mode 100644
index 0000000..ce0a3ff
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Workbench.java
@@ -0,0 +1,3935 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Francis Upton - <francisu@ieee.org> - 
+ *     		Fix for Bug 217777 [Workbench] Workbench event loop does not terminate if Display is closed
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import com.ibm.icu.util.ULocale;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Category;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.CommandManager;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.common.EventManager;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.internal.workbench.swt.ResourceUtility;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
+import org.eclipse.e4.ui.services.EContextService;
+import org.eclipse.e4.workbench.ui.menus.MenuHelper;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.ExternalActionManager;
+import org.eclipse.jface.action.ExternalActionManager.CommandCallback;
+import org.eclipse.jface.action.ExternalActionManager.IActiveChecker;
+import org.eclipse.jface.action.ExternalActionManager.IExecuteApplicable;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.LegacyActionTools;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.bindings.BindingManager;
+import org.eclipse.jface.bindings.BindingManagerEvent;
+import org.eclipse.jface.bindings.IBindingManagerListener;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.OpenStrategy;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.window.WindowManager;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.osgi.service.runnable.StartupMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.DeviceData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.ILocalWorkingSetManager;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IPerspectiveRegistry;
+import org.eclipse.ui.ISaveableFilter;
+import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.ISourceProvider;
+import org.eclipse.ui.ISourceProviderListener;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.Saveable;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.activities.IWorkbenchActivitySupport;
+import org.eclipse.ui.application.IWorkbenchConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+import org.eclipse.ui.commands.ICommandImageService;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.commands.IWorkbenchCommandSupport;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.contexts.IWorkbenchContextSupport;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.actions.CommandAction;
+import org.eclipse.ui.internal.activities.ws.WorkbenchActivitySupport;
+import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
+import org.eclipse.ui.internal.commands.CommandImageManager;
+import org.eclipse.ui.internal.commands.CommandImageService;
+import org.eclipse.ui.internal.commands.CommandService;
+import org.eclipse.ui.internal.commands.WorkbenchCommandSupport;
+import org.eclipse.ui.internal.contexts.ActiveContextSourceProvider;
+import org.eclipse.ui.internal.contexts.ContextService;
+import org.eclipse.ui.internal.contexts.WorkbenchContextSupport;
+import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager;
+import org.eclipse.ui.internal.help.WorkbenchHelpSystem;
+import org.eclipse.ui.internal.intro.IIntroRegistry;
+import org.eclipse.ui.internal.intro.IntroDescriptor;
+import org.eclipse.ui.internal.keys.BindingService;
+import org.eclipse.ui.internal.menus.FocusControlSourceProvider;
+import org.eclipse.ui.internal.menus.WorkbenchMenuService;
+import org.eclipse.ui.internal.misc.Policy;
+import org.eclipse.ui.internal.misc.StatusUtil;
+import org.eclipse.ui.internal.misc.UIStats;
+import org.eclipse.ui.internal.model.ContributionService;
+import org.eclipse.ui.internal.progress.ProgressManager;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.UIExtensionTracker;
+import org.eclipse.ui.internal.services.ActionSetSourceProvider;
+import org.eclipse.ui.internal.services.EvaluationService;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.MenuSourceProvider;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.ServiceLocatorCreator;
+import org.eclipse.ui.internal.services.SourceProviderService;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.internal.splash.EclipseSplashHandler;
+import org.eclipse.ui.internal.splash.SplashHandlerFactory;
+import org.eclipse.ui.internal.testing.WorkbenchTestable;
+import org.eclipse.ui.internal.themes.ColorDefinition;
+import org.eclipse.ui.internal.themes.FontDefinition;
+import org.eclipse.ui.internal.themes.ThemeElementHelper;
+import org.eclipse.ui.internal.themes.WorkbenchThemeManager;
+import org.eclipse.ui.internal.tweaklets.GrabFocus;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.util.PrefUtil;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.intro.IIntroManager;
+import org.eclipse.ui.keys.IBindingService;
+import org.eclipse.ui.menus.IMenuService;
+import org.eclipse.ui.model.IContributionService;
+import org.eclipse.ui.operations.IWorkbenchOperationSupport;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IEvaluationService;
+import org.eclipse.ui.services.IServiceScopes;
+import org.eclipse.ui.services.ISourceProviderService;
+import org.eclipse.ui.splash.AbstractSplashHandler;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.swt.IFocusService;
+import org.eclipse.ui.themes.IThemeManager;
+import org.eclipse.ui.views.IViewRegistry;
+import org.eclipse.ui.wizards.IWizardRegistry;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * The workbench class represents the top of the Eclipse user interface. Its
+ * primary responsibility is the management of workbench windows, dialogs,
+ * wizards, and other workbench-related windows.
+ * <p>
+ * Note that any code that is run during the creation of a workbench instance
+ * should not required access to the display.
+ * </p>
+ * <p>
+ * Note that this internal class changed significantly between 2.1 and 3.0.
+ * Applications that used to define subclasses of this internal class need to be
+ * rewritten to use the new workbench advisor API.
+ * </p>
+ */
+public final class Workbench extends EventManager implements IWorkbench {
+
+	private final class StartupProgressBundleListener implements
+			SynchronousBundleListener {
+
+		private final IProgressMonitor progressMonitor;
+
+		private final int maximumProgressCount;
+
+		// stack of names of bundles currently starting
+		private final List starting;
+
+		StartupProgressBundleListener(IProgressMonitor progressMonitor,
+				int maximumProgressCount) {
+			super();
+			this.progressMonitor = progressMonitor;
+			this.maximumProgressCount = maximumProgressCount;
+			this.starting = new ArrayList();
+		}
+
+		public void bundleChanged(BundleEvent event) {
+			int eventType = event.getType();
+			String bundleName;
+
+			synchronized (this) {
+				if (eventType == BundleEvent.STARTING) {
+					starting.add(bundleName = event.getBundle()
+							.getSymbolicName());
+				} else if (eventType == BundleEvent.STARTED) {
+					progressCount++;
+					if (progressCount <= maximumProgressCount) {
+						progressMonitor.worked(1);
+					}
+					int index = starting.lastIndexOf(event.getBundle()
+							.getSymbolicName());
+					if (index >= 0) {
+						starting.remove(index);
+					}
+					if (index != starting.size()) {
+						return; // not currently displayed
+					}
+					bundleName = index == 0 ? null : (String) starting
+							.get(index - 1);
+				} else {
+					return; // uninteresting event
+				}
+			}
+
+			String taskName;
+
+			if (bundleName == null) {
+				taskName = WorkbenchMessages.Startup_Loading_Workbench;
+			} else {
+				taskName = NLS.bind(WorkbenchMessages.Startup_Loading,
+						bundleName);
+			}
+
+			progressMonitor.subTask(taskName);
+		}
+	}
+
+	/**
+	 * Family for the early startup job.
+	 */
+	public static final String EARLY_STARTUP_FAMILY = "earlyStartup"; //$NON-NLS-1$
+
+	static final String VERSION_STRING[] = { "0.046", "2.0" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+	static final String DEFAULT_WORKBENCH_STATE_FILENAME = "workbench.xml"; //$NON-NLS-1$
+
+	/**
+	 * Holds onto the only instance of Workbench.
+	 */
+	private static Workbench instance;
+
+	/**
+	 * The testable object facade.
+	 * 
+	 * @since 3.0
+	 */
+	private static WorkbenchTestable testableObject;
+
+	/**
+	 * Signals that the workbench should create a splash implementation when
+	 * instantiated. Intial value is <code>true</code>.
+	 * 
+	 * @since 3.3
+	 */
+	private static boolean createSplash = true;
+
+	/**
+	 * The splash handler.
+	 */
+	private static AbstractSplashHandler splash;
+
+	/**
+	 * The display used for all UI interactions with this workbench.
+	 * 
+	 * @since 3.0
+	 */
+	private Display display;
+
+	private WindowManager windowManager;
+
+	private WorkbenchWindow activatedWindow;
+
+	private EditorHistory editorHistory;
+
+	private boolean runEventLoop = true;
+
+	private boolean isStarting = true;
+
+	private boolean isClosing = false;
+
+	/**
+	 * PlatformUI return code (as opposed to IPlatformRunnable return code).
+	 */
+	private int returnCode = PlatformUI.RETURN_UNSTARTABLE;
+
+	/**
+	 * Advisor providing application-specific configuration and customization of
+	 * the workbench.
+	 * 
+	 * @since 3.0
+	 */
+	private WorkbenchAdvisor advisor;
+
+	/**
+	 * Object for configuring the workbench. Lazily initialized to an instance
+	 * unique to the workbench instance.
+	 * 
+	 * @since 3.0
+	 */
+	private WorkbenchConfigurer workbenchConfigurer;
+
+	// for dynamic UI
+	/**
+	 * ExtensionEventHandler handles extension life-cycle events.
+	 */
+	private ExtensionEventHandler extensionEventHandler;
+
+	/**
+	 * A count of how many large updates are going on. This tracks nesting of
+	 * requests to disable services during a large update -- similar to the
+	 * <code>setRedraw</code> functionality on <code>Control</code>. When this
+	 * value becomes greater than zero, services are disabled. When this value
+	 * becomes zero, services are enabled. Please see
+	 * <code>largeUpdateStart()</code> and <code>largeUpdateEnd()</code>.
+	 */
+	private int largeUpdates = 0;
+
+	/**
+	 * The service locator maintained by the workbench. These services are
+	 * initialized during workbench during the <code>init</code> method.
+	 */
+	private final ServiceLocator serviceLocator;
+
+	/**
+	 * A count of how many plug-ins were loaded while restoring the workbench
+	 * state. Initially -1 for unknown number.
+	 */
+	private int progressCount = -1;
+
+	/**
+	 * Listener list for registered IWorkbenchListeners .
+	 */
+	private ListenerList workbenchListeners = new ListenerList(
+			ListenerList.IDENTITY);
+
+	private ServiceTracker locationTracker;
+
+	private ISourceProviderListener sourceListener;
+
+	/**
+	 * Creates a new workbench.
+	 * 
+	 * @param display
+	 *            the display to be used for all UI interactions with the
+	 *            workbench
+	 * @param advisor
+	 *            the application-specific advisor that configures and
+	 *            specializes this workbench instance
+	 * @since 3.0
+	 */
+	private Workbench(Display display, WorkbenchAdvisor advisor) {
+		super();
+		StartupThreading.setWorkbench(this);
+		if (instance != null && instance.isRunning()) {
+			throw new IllegalStateException(
+					WorkbenchMessages.Workbench_CreatingWorkbenchTwice);
+		}
+		Assert.isNotNull(display);
+		Assert.isNotNull(advisor);
+		this.advisor = advisor;
+		this.display = display;
+		Workbench.instance = this;
+
+		// hook in the e4 workbench
+		IEclipseContext serviceContext = EclipseContextFactory
+				.getServiceContext(Activator.getDefault().getContext());
+		IEclipseContext appContext = EclipseContextFactory.create(
+				serviceContext, null);
+		appContext.set(IContextConstants.DEBUG_STRING, "application"); //$NON-NLS-1$
+		Location instanceLocation = getInstanceLocation();
+		PackageAdmin packageAdmin = (PackageAdmin) appContext
+				.get(PackageAdmin.class.getName());
+		String engineURI = "bundleclass://org.eclipse.e4.ui.workbench.swt/"; //$NON-NLS-1$
+		engineURI += "org.eclipse.e4.ui.workbench.swt.internal.PartRenderingEngine"; //$NON-NLS-1$
+
+		e4Workbench = new org.eclipse.e4.workbench.ui.internal.Workbench(
+				instanceLocation, Platform.getExtensionRegistry(),
+				packageAdmin, appContext, new WorkbenchWindowHandler(),
+				engineURI);
+		e4Context = e4Workbench.getContext();
+		e4Context.set(getClass().getName(), this);
+		e4Context.set(IWorkbench.class.getName(), this);
+
+		IServiceLocatorCreator slc = new ServiceLocatorCreator();
+		serviceLocator = (ServiceLocator) slc.createServiceLocator(null, null,
+				new IDisposable() {
+					public void dispose() {
+						final Display display = getDisplay();
+						if (display != null && !display.isDisposed()) {
+							MessageDialog
+									.openInformation(
+											null,
+											WorkbenchMessages.Workbench_NeedsClose_Title,
+											WorkbenchMessages.Workbench_NeedsClose_Message);
+							close(PlatformUI.RETURN_RESTART, true);
+						}
+					}
+				});
+		serviceLocator.setContext(e4Context);
+		serviceLocator.registerService(IServiceLocatorCreator.class, slc);
+		serviceLocator.registerService(IWorkbenchLocationService.class,
+				new WorkbenchLocationService(IServiceScopes.WORKBENCH_SCOPE,
+						this, null, null, null, null, 0));
+		// added back for legacy reasons
+		serviceLocator.registerService(IWorkbench.class, this);
+	}
+
+	public Location getInstanceLocation() {
+		if (locationTracker == null) {
+			final BundleContext context = WorkbenchPlugin.getDefault()
+					.getBundleContext();
+			Filter filter = null;
+			try {
+				filter = context.createFilter(Location.INSTANCE_FILTER);
+			} catch (InvalidSyntaxException e) {
+				// ignore this. It should never happen as we have tested the
+				// above format.
+			}
+			locationTracker = new ServiceTracker(context, filter, null);
+			locationTracker.open();
+		}
+		return (Location) locationTracker.getService();
+	}
+
+	private MApplication createE4Model() {
+		MApplication app = MApplicationFactory.eINSTANCE.createApplication();
+		return app;
+	}
+
+	/**
+	 * Returns the one and only instance of the workbench, if there is one.
+	 * 
+	 * @return the workbench, or <code>null</code> if the workbench has not been
+	 *         created, or has been created and already completed
+	 */
+	public static final Workbench getInstance() {
+		return instance;
+	}
+
+	/**
+	 * Creates the workbench and associates it with the the given display and
+	 * workbench advisor, and runs the workbench UI. This entails processing and
+	 * dispatching events until the workbench is closed or restarted.
+	 * <p>
+	 * This method is intended to be called by <code>PlatformUI</code>. Fails if
+	 * the workbench UI has already been created.
+	 * </p>
+	 * <p>
+	 * The display passed in must be the default display.
+	 * </p>
+	 * 
+	 * @param display
+	 *            the display to be used for all UI interactions with the
+	 *            workbench
+	 * @param advisor
+	 *            the application-specific advisor that configures and
+	 *            specializes the workbench
+	 * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
+	 *         exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
+	 *         workbench was terminated with a call to
+	 *         {@link IWorkbench#restart IWorkbench.restart}; other values
+	 *         reserved for future use
+	 */
+	public static final int createAndRunWorkbench(final Display display,
+			final WorkbenchAdvisor advisor) {
+		final int[] returnCode = new int[1];
+		Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
+			public void run() {
+				ULocale.setDefault(new ULocale(Platform.getNL()
+						+ Platform.getNLExtensions()));
+				// create the workbench instance
+				Workbench workbench = new Workbench(display, advisor);
+				// run the workbench event loop
+				returnCode[0] = workbench.runUI();
+			}
+		});
+		return returnCode[0];
+	}
+
+	/**
+	 * Creates the <code>Display</code> to be used by the workbench.
+	 * 
+	 * @return the display
+	 */
+	public static Display createDisplay() {
+		// setup the application name used by SWT to lookup resources on some
+		// platforms
+		String applicationName = WorkbenchPlugin.getDefault().getAppName();
+		if (applicationName != null) {
+			Display.setAppName(applicationName);
+		}
+
+		// create the display
+		Display newDisplay = Display.getCurrent();
+		if (newDisplay == null) {
+			if (Policy.DEBUG_SWT_GRAPHICS || Policy.DEBUG_SWT_DEBUG) {
+				DeviceData data = new DeviceData();
+				if (Policy.DEBUG_SWT_GRAPHICS) {
+					data.tracking = true;
+				}
+				if (Policy.DEBUG_SWT_DEBUG) {
+					data.debug = true;
+				}
+				newDisplay = new Display(data);
+			} else {
+				newDisplay = new Display();
+			}
+		}
+
+		// workaround for 1GEZ9UR and 1GF07HN
+		newDisplay.setWarnings(false);
+
+		// Set the priority higher than normal so as to be higher
+		// than the JobManager.
+		Thread.currentThread().setPriority(
+				Math.min(Thread.MAX_PRIORITY, Thread.NORM_PRIORITY + 1));
+
+		initializeImages();
+
+		return newDisplay;
+	}
+
+	/**
+	 * Create the splash wrapper and set it to work.
+	 * 
+	 * @since 3.3
+	 */
+	private void createSplashWrapper() {
+		final Display display = getDisplay();
+		String splashLoc = System
+				.getProperty("org.eclipse.equinox.launcher.splash.location"); //$NON-NLS-1$
+		final Image background = loadImage(splashLoc);
+
+		SafeRunnable run = new SafeRunnable() {
+
+			public void run() throws Exception {
+				if (!WorkbenchPlugin.isSplashHandleSpecified()) {
+					createSplash = false;
+					return;
+				}
+
+				// create the splash
+				getSplash();
+				if (splash == null) {
+					createSplash = false;
+					return;
+				}
+
+				Shell splashShell = splash.getSplash();
+				if (splashShell == null) {
+					splashShell = WorkbenchPlugin.getSplashShell(display);
+
+					if (splashShell == null)
+						return;
+					if (background != null)
+						splashShell.setBackgroundImage(background);
+				}
+
+				Dictionary properties = new Hashtable();
+				properties.put(Constants.SERVICE_RANKING, new Integer(
+						Integer.MAX_VALUE));
+				BundleContext context = WorkbenchPlugin.getDefault()
+						.getBundleContext();
+				final ServiceRegistration registration[] = new ServiceRegistration[1];
+				StartupMonitor startupMonitor = new StartupMonitor() {
+
+					public void applicationRunning() {
+						splash.dispose();
+						if (background != null)
+							background.dispose();
+						registration[0].unregister(); // unregister ourself
+						WorkbenchPlugin.unsetSplashShell(display);
+					}
+
+					public void update() {
+						// do nothing - we come into the picture far too late
+						// for this to be relevant
+					}
+				};
+				registration[0] = context.registerService(
+						StartupMonitor.class.getName(), startupMonitor,
+						properties);
+
+				splash.init(splashShell);
+			}
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.util.SafeRunnable#handleException(java.lang
+			 * .Throwable)
+			 */
+			public void handleException(Throwable e) {
+				StatusManager.getManager().handle(
+						StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
+								"Could not instantiate splash", e)); //$NON-NLS-1$
+				createSplash = false;
+				splash = null;
+				if (background != null)
+					background.dispose();
+
+			}
+		};
+		SafeRunner.run(run);
+	}
+
+	/**
+	 * Load an image from a filesystem path.
+	 * 
+	 * @param splashLoc
+	 *            the location to load from
+	 * @return the image or <code>null</code>
+	 * @since 3.3
+	 */
+	private Image loadImage(String splashLoc) {
+		Image background = null;
+		if (splashLoc != null) {
+			InputStream input = null;
+			try {
+				input = new BufferedInputStream(new FileInputStream(splashLoc));
+				background = new Image(display, input);
+			} catch (SWTException e) {
+				StatusManager.getManager().handle(
+						StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
+			} catch (IOException e) {
+				StatusManager.getManager().handle(
+						StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
+			} finally {
+				if (input != null) {
+					try {
+						input.close();
+					} catch (IOException e) {
+						// he's done for
+					}
+				}
+			}
+		}
+		return background;
+	}
+
+	/**
+	 * Return the splash handler for this application. If none is specifically
+	 * provided the default Eclipse implementation is returned.
+	 * 
+	 * @return the splash handler for this application or <code>null</code>
+	 * @since 3.3
+	 */
+	private static AbstractSplashHandler getSplash() {
+		if (!createSplash)
+			return null;
+
+		if (splash == null) {
+
+			IProduct product = Platform.getProduct();
+			if (product != null)
+				splash = SplashHandlerFactory.findSplashHandlerFor(product);
+
+			if (splash == null)
+				splash = new EclipseSplashHandler();
+		}
+		return splash;
+	}
+
+	/**
+	 * Returns the testable object facade, for use by the test harness.
+	 * 
+	 * @return the testable object facade
+	 * @since 3.0
+	 */
+	public static WorkbenchTestable getWorkbenchTestable() {
+		if (testableObject == null) {
+			testableObject = new WorkbenchTestable();
+		}
+		return testableObject;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 * 
+	 * @since 3.2
+	 */
+	public void addWorkbenchListener(IWorkbenchListener listener) {
+		workbenchListeners.add(listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 * 
+	 * @since 3.2
+	 */
+	public void removeWorkbenchListener(IWorkbenchListener listener) {
+		workbenchListeners.remove(listener);
+	}
+
+	/**
+	 * Fire workbench preShutdown event, stopping at the first one to veto
+	 * 
+	 * @param forced
+	 *            flag indicating whether the shutdown is being forced
+	 * @return <code>true</code> to allow the workbench to proceed with
+	 *         shutdown, <code>false</code> to veto a non-forced shutdown
+	 * @since 3.2
+	 */
+	boolean firePreShutdown(final boolean forced) {
+		Object list[] = workbenchListeners.getListeners();
+		for (int i = 0; i < list.length; i++) {
+			final IWorkbenchListener l = (IWorkbenchListener) list[i];
+			final boolean[] result = new boolean[] { false };
+			SafeRunnable.run(new SafeRunnable() {
+				public void run() {
+					result[0] = l.preShutdown(Workbench.this, forced);
+				}
+			});
+			if (!result[0]) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Fire workbench postShutdown event.
+	 * 
+	 * @since 3.2
+	 */
+	void firePostShutdown() {
+		Object list[] = workbenchListeners.getListeners();
+		for (int i = 0; i < list.length; i++) {
+			final IWorkbenchListener l = (IWorkbenchListener) list[i];
+			SafeRunnable.run(new SafeRunnable() {
+				public void run() {
+					l.postShutdown(Workbench.this);
+				}
+			});
+		}
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public void addWindowListener(IWindowListener l) {
+		addListenerObject(l);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public void removeWindowListener(IWindowListener l) {
+		removeListenerObject(l);
+	}
+
+	/**
+	 * Fire window opened event.
+	 * 
+	 * @param window
+	 *            The window which just opened; should not be <code>null</code>.
+	 */
+	protected void fireWindowOpened(final IWorkbenchWindow window) {
+		Object list[] = getListeners();
+		for (int i = 0; i < list.length; i++) {
+			final IWindowListener l = (IWindowListener) list[i];
+			SafeRunner.run(new SafeRunnable() {
+				public void run() {
+					l.windowOpened(window);
+				}
+			});
+		}
+	}
+
+	/**
+	 * Fire window closed event.
+	 * 
+	 * @param window
+	 *            The window which just closed; should not be <code>null</code>.
+	 */
+	protected void fireWindowClosed(final IWorkbenchWindow window) {
+		if (activatedWindow == window) {
+			// Do not hang onto it so it can be GC'ed
+			activatedWindow = null;
+		}
+
+		Object list[] = getListeners();
+		for (int i = 0; i < list.length; i++) {
+			final IWindowListener l = (IWindowListener) list[i];
+			SafeRunner.run(new SafeRunnable() {
+				public void run() {
+					l.windowClosed(window);
+				}
+			});
+		}
+	}
+
+	/**
+	 * Fire window activated event.
+	 * 
+	 * @param window
+	 *            The window which was just activated; should not be
+	 *            <code>null</code>.
+	 */
+	protected void fireWindowActivated(final IWorkbenchWindow window) {
+		Object list[] = getListeners();
+		for (int i = 0; i < list.length; i++) {
+			final IWindowListener l = (IWindowListener) list[i];
+			SafeRunner.run(new SafeRunnable() {
+				public void run() {
+					l.windowActivated(window);
+				}
+			});
+		}
+	}
+
+	/**
+	 * Fire window deactivated event.
+	 * 
+	 * @param window
+	 *            The window which was just deactivated; should not be
+	 *            <code>null</code>.
+	 */
+	protected void fireWindowDeactivated(final IWorkbenchWindow window) {
+		Object list[] = getListeners();
+		for (int i = 0; i < list.length; i++) {
+			final IWindowListener l = (IWindowListener) list[i];
+			SafeRunner.run(new SafeRunnable() {
+				public void run() {
+					l.windowDeactivated(window);
+				}
+			});
+		}
+	}
+
+	/**
+	 * Closes the workbench. Assumes that the busy cursor is active.
+	 * 
+	 * @param force
+	 *            true if the close is mandatory, and false if the close is
+	 *            allowed to fail
+	 * @return true if the close succeeded, and false otherwise
+	 */
+	private boolean busyClose(final boolean force) {
+
+		// notify the advisor of preShutdown and allow it to veto if not forced
+		isClosing = advisor.preShutdown();
+		if (!force && !isClosing) {
+			return false;
+		}
+
+		// notify regular workbench clients of preShutdown and allow them to
+		// veto if not forced
+		isClosing = firePreShutdown(force);
+		if (!force && !isClosing) {
+			return false;
+		}
+
+		// save any open editors if they are dirty
+		isClosing = saveAllEditors(!force);
+		if (!force && !isClosing) {
+			return false;
+		}
+
+		boolean closeEditors = !force
+				&& PrefUtil.getAPIPreferenceStore().getBoolean(
+						IWorkbenchPreferenceConstants.CLOSE_EDITORS_ON_EXIT);
+		if (closeEditors) {
+			SafeRunner.run(new SafeRunnable() {
+				public void run() {
+					IWorkbenchWindow windows[] = getWorkbenchWindows();
+					for (int i = 0; i < windows.length; i++) {
+						IWorkbenchPage pages[] = windows[i].getPages();
+						for (int j = 0; j < pages.length; j++) {
+							isClosing = isClosing
+									&& pages[j].closeAllEditors(false);
+						}
+					}
+				}
+			});
+			if (!force && !isClosing) {
+				return false;
+			}
+		}
+
+		if (getWorkbenchConfigurer().getSaveAndRestore()) {
+			SafeRunner.run(new SafeRunnable() {
+				public void run() {
+
+					org.eclipse.e4.workbench.ui.internal.Activator
+							.trace(org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_WORKBENCH,
+									"saveing model to " + getXmiLocation(), null); //$NON-NLS-1$
+					try {
+						// because we created the model we need to set the
+						// resource correctly
+						Resource resource = new XMIResourceImpl();
+						resource.getContents().add(
+								(EObject) e4Workbench.getModel());
+						String resourceLoc = getXmiLocation();
+						resource.setURI(URI.createFileURI(resourceLoc));
+
+						resource.save(null);
+					} catch (IOException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+
+					XMLMemento mem = recordWorkbenchState();
+					// Save the IMemento to a file.
+					saveMementoToFile(mem);
+				}
+
+				public void handleException(Throwable e) {
+					String message;
+					if (e.getMessage() == null) {
+						message = WorkbenchMessages.ErrorClosingNoArg;
+					} else {
+						message = NLS.bind(
+								WorkbenchMessages.ErrorClosingOneArg,
+								e.getMessage());
+					}
+
+					if (!MessageDialog.openQuestion(null,
+							WorkbenchMessages.Error, message)) {
+						isClosing = false;
+					}
+				}
+			});
+		}
+		if (!force && !isClosing) {
+			return false;
+		}
+
+		SafeRunner.run(new SafeRunnable(WorkbenchMessages.ErrorClosing) {
+			public void run() {
+				if (isClosing || force) {
+					isClosing = windowManager.close();
+				}
+			}
+		});
+
+		if (!force && !isClosing) {
+			return false;
+		}
+
+		shutdown();
+
+		runEventLoop = false;
+		return true;
+	}
+
+	private String getXmiLocation() {
+		return WorkbenchPlugin.getDefault().getDataLocation()
+				.append("workbench.xmi").toOSString(); //$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#saveAllEditors(boolean)
+	 */
+	public boolean saveAllEditors(boolean confirm) {
+		final boolean finalConfirm = confirm;
+		final boolean[] result = new boolean[1];
+		result[0] = true;
+
+		SafeRunner.run(new SafeRunnable(WorkbenchMessages.ErrorClosing) {
+			public void run() {
+				// Collect dirtyParts
+				ArrayList dirtyParts = new ArrayList();
+				ArrayList dirtyEditorsInput = new ArrayList();
+				IWorkbenchWindow windows[] = getWorkbenchWindows();
+				for (int i = 0; i < windows.length; i++) {
+					IWorkbenchPage pages[] = windows[i].getPages();
+					for (int j = 0; j < pages.length; j++) {
+						WorkbenchPage page = (WorkbenchPage) pages[j];
+
+						ISaveablePart[] parts = page.getDirtyParts();
+
+						for (int k = 0; k < parts.length; k++) {
+							ISaveablePart part = parts[k];
+
+							if (part.isSaveOnCloseNeeded()) {
+								if (part instanceof IEditorPart) {
+									IEditorPart editor = (IEditorPart) part;
+									if (!dirtyEditorsInput.contains(editor
+											.getEditorInput())) {
+										dirtyParts.add(editor);
+										dirtyEditorsInput.add(editor
+												.getEditorInput());
+									}
+								} else {
+									dirtyParts.add(part);
+								}
+							}
+						}
+					}
+				}
+				IShellProvider shellProvider;
+				IRunnableContext runnableContext;
+				IWorkbenchWindow w = getActiveWorkbenchWindow();
+				if (w == null && windows.length > 0) {
+					w = windows[0];
+				}
+				if (w != null) {
+					shellProvider = w;
+					runnableContext = w;
+				} else {
+					shellProvider = new IShellProvider() {
+						public Shell getShell() {
+							return null;
+						}
+					};
+					runnableContext = new ProgressMonitorDialog(null);
+				}
+				// The fourth parameter is true to also save saveables from
+				// non-part sources, see bug 139004.
+				result[0] = EditorManager.saveAll(dirtyParts, finalConfirm,
+						false, true, runnableContext, shellProvider);
+			}
+		});
+		return result[0];
+	}
+
+	/**
+	 * Opens a new workbench window and page with a specific perspective.
+	 * 
+	 * Assumes that busy cursor is active.
+	 */
+	private IWorkbenchWindow busyOpenWorkbenchWindow(final String perspID,
+			final IAdaptable input) throws WorkbenchException {
+		// Create a workbench window (becomes active window)
+		final WorkbenchWindow newWindowArray[] = new WorkbenchWindow[1];
+		StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+			public void runWithException() {
+				newWindowArray[0] = newWorkbenchWindow();
+			}
+		});
+
+		final WorkbenchWindow newWindow = newWindowArray[0];
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				// newWindow.create(); // must be created before adding to
+				// window
+				// manager
+			}
+		});
+		windowManager.add(newWindow);
+
+		final WorkbenchException[] exceptions = new WorkbenchException[1];
+		// Create the initial page.
+		if (perspID != null) {
+			StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+
+				public void runWithException() {
+					try {
+						newWindow.busyOpenPage(perspID, input);
+					} catch (WorkbenchException e) {
+						windowManager.remove(newWindow);
+						exceptions[0] = e;
+					}
+				}
+			});
+		}
+		if (exceptions[0] != null)
+			throw exceptions[0];
+
+		// Open window after opening page, to avoid flicker.
+		StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				newWindow.open();
+			}
+		});
+
+		return newWindow;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public boolean close() {
+		return close(PlatformUI.RETURN_OK, false);
+	}
+
+	/**
+	 * Closes the workbench, returning the given return code from the run
+	 * method. If forced, the workbench is closed no matter what.
+	 * 
+	 * @param returnCode
+	 *            {@link PlatformUI#RETURN_OK RETURN_OK}for normal exit;
+	 *            {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
+	 *            workbench was terminated with a call to
+	 *            {@link IWorkbench#restart IWorkbench.restart};
+	 *            {@link PlatformUI#RETURN_EMERGENCY_CLOSE} for an emergency
+	 *            shutdown {@link PlatformUI#RETURN_UNSTARTABLE
+	 *            RETURN_UNSTARTABLE}if the workbench could not be started;
+	 *            other values reserved for future use
+	 * 
+	 * @param force
+	 *            true to force the workbench close, and false for a "soft"
+	 *            close that can be canceled
+	 * @return true if the close was successful, and false if the close was
+	 *         canceled
+	 */
+	/* package */
+	boolean close(int returnCode, final boolean force) {
+		this.returnCode = returnCode;
+		final boolean[] ret = new boolean[1];
+		BusyIndicator.showWhile(null, new Runnable() {
+			public void run() {
+				ret[0] = busyClose(force);
+			}
+		});
+		return ret[0];
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkbenchWindow getActiveWorkbenchWindow() {
+		// Return null if called from a non-UI thread.
+		// This is not spec'ed behaviour and is misleading, however this is how
+		// it
+		// worked in 2.1 and we cannot change it now.
+		// For more details, see [Bug 57384] [RCP] Main window not active on
+		// startup
+		if (Display.getCurrent() == null) {
+			return null;
+		}
+
+		// Look at the current shell and up its parent
+		// hierarchy for a workbench window.
+		Control shell = display.getActiveShell();
+		while (shell != null) {
+			Object data = shell.getData();
+			if (data instanceof IWorkbenchWindow) {
+				return (IWorkbenchWindow) data;
+			}
+			shell = shell.getParent();
+		}
+
+		// Look for the window that was last known being
+		// the active one
+		WorkbenchWindow win = getActivatedWindow();
+		if (win != null) {
+			return win;
+		}
+
+		win = (WorkbenchWindow) e4Context
+				.get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+		if (win != null) {
+			return win;
+		}
+
+		// Look at all the shells and pick the first one
+		// that is a workbench window.
+		Shell shells[] = display.getShells();
+		for (int i = 0; i < shells.length; i++) {
+			Object data = shells[i].getData();
+			if (data instanceof IWorkbenchWindow) {
+				return (IWorkbenchWindow) data;
+			}
+		}
+
+		// Can't find anything!
+		return null;
+	}
+
+	/*
+	 * Returns the editor history.
+	 */
+	public EditorHistory getEditorHistory() {
+		return (EditorHistory) e4Context.get(EditorHistory.class.getName());
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IEditorRegistry getEditorRegistry() {
+		return WorkbenchPlugin.getDefault().getEditorRegistry();
+	}
+
+	/*
+	 * Returns the number for a new window. This will be the first number > 0
+	 * which is not used to identify another window in the workbench.
+	 */
+	private int getNewWindowNumber() {
+		// Get window list.
+		Window[] windows = windowManager.getWindows();
+		int count = windows.length;
+
+		// Create an array of booleans (size = window count).
+		// Cross off every number found in the window list.
+		boolean checkArray[] = new boolean[count];
+		for (int nX = 0; nX < count; nX++) {
+			if (windows[nX] instanceof WorkbenchWindow) {
+				WorkbenchWindow ww = (WorkbenchWindow) windows[nX];
+				int index = ww.getNumber() - 1;
+				if (index >= 0 && index < count) {
+					checkArray[index] = true;
+				}
+			}
+		}
+
+		// Return first index which is not used.
+		// If no empty index was found then every slot is full.
+		// Return next index.
+		for (int index = 0; index < count; index++) {
+			if (!checkArray[index]) {
+				return index + 1;
+			}
+		}
+		return count + 1;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkbenchOperationSupport getOperationSupport() {
+		return WorkbenchPlugin.getDefault().getOperationSupport();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IPerspectiveRegistry getPerspectiveRegistry() {
+		return WorkbenchPlugin.getDefault().getPerspectiveRegistry();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public PreferenceManager getPreferenceManager() {
+		return WorkbenchPlugin.getDefault().getPreferenceManager();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IPreferenceStore getPreferenceStore() {
+		return WorkbenchPlugin.getDefault().getPreferenceStore();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public ISharedImages getSharedImages() {
+		return WorkbenchPlugin.getDefault().getSharedImages();
+	}
+
+	/**
+	 * Returns the window manager for this workbench.
+	 * 
+	 * @return the window manager
+	 */
+	/* package */
+	WindowManager getWindowManager() {
+		return windowManager;
+	}
+
+	/*
+	 * Answer the workbench state file.
+	 */
+	private File getWorkbenchStateFile() {
+		IPath path = WorkbenchPlugin.getDefault().getDataLocation();
+		if (path == null) {
+			return null;
+		}
+		path = path.append(DEFAULT_WORKBENCH_STATE_FILENAME);
+		return path.toFile();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public int getWorkbenchWindowCount() {
+		return windowManager.getWindowCount();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkbenchWindow[] getWorkbenchWindows() {
+		Window[] windows = windowManager.getWindows();
+		IWorkbenchWindow[] dwindows = new IWorkbenchWindow[windows.length];
+		System.arraycopy(windows, 0, dwindows, 0, windows.length);
+		return dwindows;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkingSetManager getWorkingSetManager() {
+		return WorkbenchPlugin.getDefault().getWorkingSetManager();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public ILocalWorkingSetManager createLocalWorkingSetManager() {
+		return new LocalWorkingSetManager(WorkbenchPlugin.getDefault()
+				.getBundleContext());
+	}
+
+	private static final String APPLICATION_CSS_RESOURCES_ARG = "-applicationCSSResources"; //$NON-NLS-1$
+	private static final String APPLICATION_CSS_RESOURCES = "applicationCSSResources"; //$NON-NLS-1$
+	private static final String APPLICATION_CSS_ARG = "-applicationCSS"; //$NON-NLS-1$
+	private static final String APPLICATION_CSS = "applicationCSS"; //$NON-NLS-1$
+
+	private Map<String, String> processArgs(String[] args) {
+		HashMap<String, String> argsList = new HashMap<String, String>();
+		for (int i = 0; i < args.length; i++) {
+			if (APPLICATION_CSS_ARG.equals(args[i])) {
+				argsList.put(APPLICATION_CSS, args[++i]);
+			} else if (APPLICATION_CSS_RESOURCES_ARG.equals(args[i])) {
+				argsList.put(APPLICATION_CSS_RESOURCES, args[++i]);
+			}
+		}
+		return argsList;
+	}
+
+	/**
+	 * Initializes the workbench now that the display is created.
+	 * 
+	 * @return true if init succeeded.
+	 */
+	private boolean init() {
+		// setup debug mode if required.
+		if (WorkbenchPlugin.getDefault().isDebugging()) {
+			WorkbenchPlugin.DEBUG = true;
+			ModalContext.setDebugMode(true);
+		}
+
+		// Set up the JFace preference store
+		JFaceUtil.initializeJFacePreferences();
+
+		MApplication model = createE4Model();
+		e4Workbench.setWorkbenchModel(model);
+
+		// create workbench window manager
+		windowManager = new WindowManager();
+
+		// BEGIN: early e4 services
+		final Map<String, String> argsList = processArgs(Platform
+				.getApplicationArgs());
+		String cssURIr = argsList.get(APPLICATION_CSS);
+		String cssResourcesURIr = argsList.get(APPLICATION_CSS_RESOURCES);
+		IProduct product = Platform.getProduct();
+		if (product != null) {
+			if (cssURIr == null) {
+				cssURIr = product.getProperty(APPLICATION_CSS);
+			}
+			if (cssResourcesURIr == null) {
+				cssResourcesURIr = product
+						.getProperty(APPLICATION_CSS_RESOURCES);
+			}
+		}
+		final String cssURI = cssURIr;
+		final String cssResourcesURI = cssResourcesURIr;
+
+		if (cssURI != null) {
+			StartupThreading.runWithoutExceptions(new StartupRunnable() {
+				public void runWithException() {
+					CSSStylingSupport.initializeStyling(display, cssURI,
+							cssResourcesURI, e4Context);
+				}
+			});
+		}
+		final PackageAdmin packageAdmin = (PackageAdmin) e4Context
+				.get(PackageAdmin.class.getName());
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				e4Context.set(IResourceUtiltities.class.getName(),
+						new ResourceUtility(packageAdmin));
+			}
+		});
+		e4Context.set(IExtensionTracker.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (tracker == null) {
+					tracker = new UIExtensionTracker(getDisplay());
+				}
+				return tracker;
+			}
+		});
+		e4Context.set(IWorkbenchActivitySupport.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						if (workbenchActivitySupport == null) {
+							workbenchActivitySupport = new WorkbenchActivitySupport();
+						}
+						return workbenchActivitySupport;
+					}
+				});
+		// END: early e4 services
+
+		WorkbenchPlugin.getDefault().initializeContext(e4Context);
+
+		// TODO Correctly order service initialization
+		// there needs to be some serious consideration given to
+		// the services, and hooking them up in the correct order
+		final EvaluationService evaluationService = new EvaluationService();
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				serviceLocator.registerService(IEvaluationService.class,
+						evaluationService);
+			}
+		});
+
+		// Initialize the activity support.
+
+		activityHelper = ActivityPersistanceHelper.getInstance();
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				WorkbenchImages.getImageRegistry();
+			}
+		});
+		initializeDefaultServices();
+		initializeFonts();
+		initializeColors();
+		initializeApplicationColors();
+
+		// now that the workbench is sufficiently initialized, let the advisor
+		// have a turn.
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				advisor.internalBasicInitialize(getWorkbenchConfigurer());
+			}
+		});
+
+		// configure use of color icons in toolbars
+		boolean useColorIcons = PrefUtil.getInternalPreferenceStore()
+				.getBoolean(IPreferenceConstants.COLOR_ICONS);
+		ActionContributionItem.setUseColorIconsInToolbars(useColorIcons);
+
+		// initialize workbench single-click vs double-click behavior
+		initializeSingleClickOption();
+
+		initializeWorkbenchImages();
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				((GrabFocus) Tweaklets.get(GrabFocus.KEY)).init(getDisplay());
+			}
+		});
+
+		// attempt to restore a previous workbench state
+		try {
+			UIStats.start(UIStats.RESTORE_WORKBENCH, "Workbench"); //$NON-NLS-1$
+
+			final boolean bail[] = new boolean[1];
+			StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+				public void runWithException() throws Throwable {
+					advisor.preStartup();
+
+					if (isClosing() || !advisor.openWindows()) {
+						bail[0] = true;
+					}
+				}
+			});
+
+			if (bail[0])
+				return false;
+
+		} finally {
+			UIStats.end(UIStats.RESTORE_WORKBENCH, this, "Workbench"); //$NON-NLS-1$
+		}
+
+		forceOpenPerspective();
+
+		return true;
+	}
+
+	/**
+	 * 
+	 */
+	private void initializeWorkbenchImages() {
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+			public void runWithException() {
+				WorkbenchImages.getDescriptors();
+			}
+		});
+	}
+
+	/**
+	 * Establishes the relationship between JFace actions and the command
+	 * manager.
+	 */
+	private void initializeCommandResolver() {
+		ExternalActionManager.getInstance().setCallback(
+				new CommandCallback(bindingManager, commandManager,
+						new IActiveChecker() {
+							public final boolean isActive(final String commandId) {
+								return getActivitySupport()
+										.getActivityManager()
+										.getIdentifier(commandId).isEnabled();
+							}
+						}, new IExecuteApplicable() {
+							public boolean isApplicable(IAction action) {
+								return !(action instanceof CommandAction);
+							}
+						}));
+	}
+
+	/**
+	 * Initialize colors defined by the new colorDefinitions extension point.
+	 * Note this will be rolled into initializeColors() at some point.
+	 * 
+	 * @since 3.0
+	 */
+	private void initializeApplicationColors() {
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				ColorDefinition[] colorDefinitions = WorkbenchPlugin
+						.getDefault().getThemeRegistry().getColors();
+				ThemeElementHelper
+						.populateRegistry(
+								getThemeManager().getTheme(
+										IThemeManager.DEFAULT_THEME),
+								colorDefinitions,
+								PrefUtil.getInternalPreferenceStore());
+			}
+		});
+	}
+
+	private void initializeSingleClickOption() {
+		IPreferenceStore store = WorkbenchPlugin.getDefault()
+				.getPreferenceStore();
+		boolean openOnSingleClick = store
+				.getBoolean(IPreferenceConstants.OPEN_ON_SINGLE_CLICK);
+		boolean selectOnHover = store
+				.getBoolean(IPreferenceConstants.SELECT_ON_HOVER);
+		boolean openAfterDelay = store
+				.getBoolean(IPreferenceConstants.OPEN_AFTER_DELAY);
+		int singleClickMethod = openOnSingleClick ? OpenStrategy.SINGLE_CLICK
+				: OpenStrategy.DOUBLE_CLICK;
+		if (openOnSingleClick) {
+			if (selectOnHover) {
+				singleClickMethod |= OpenStrategy.SELECT_ON_HOVER;
+			}
+			if (openAfterDelay) {
+				singleClickMethod |= OpenStrategy.ARROW_KEYS_OPEN;
+			}
+		}
+		OpenStrategy.setOpenMethod(singleClickMethod);
+	}
+
+	/*
+	 * Initializes the workbench fonts with the stored values.
+	 */
+	private void initializeFonts() {
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				FontDefinition[] fontDefinitions = WorkbenchPlugin.getDefault()
+						.getThemeRegistry().getFonts();
+
+				ThemeElementHelper.populateRegistry(getThemeManager()
+						.getCurrentTheme(), fontDefinitions, PrefUtil
+						.getInternalPreferenceStore());
+			}
+		});
+	}
+
+	/*
+	 * Initialize the workbench images.
+	 * 
+	 * @param windowImages An array of the descriptors of the images to be used
+	 * in the corner of each window, or <code>null</code> if none. It is
+	 * expected that the array will contain the same icon, rendered at different
+	 * sizes.
+	 * 
+	 * @since 3.0
+	 */
+	private static void initializeImages() {
+		ImageDescriptor[] windowImages = WorkbenchPlugin.getDefault()
+				.getWindowImages();
+		if (windowImages == null) {
+			return;
+		}
+
+		Image[] images = new Image[windowImages.length];
+		for (int i = 0; i < windowImages.length; ++i) {
+			images[i] = windowImages[i].createImage();
+		}
+		Window.setDefaultImages(images);
+	}
+
+	/*
+	 * Take the workbenches' images out of the shared registry.
+	 * 
+	 * @since 3.0
+	 */
+	private void uninitializeImages() {
+		WorkbenchImages.dispose();
+		Image[] images = Window.getDefaultImages();
+		Window.setDefaultImage(null);
+		for (int i = 0; i < images.length; i++) {
+			images[i].dispose();
+		}
+	}
+
+	/*
+	 * Initialize the workbench colors.
+	 * 
+	 * @since 3.0
+	 */
+	private void initializeColors() {
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+			public void runWithException() {
+				WorkbenchColors.startup();
+			}
+		});
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public boolean isClosing() {
+		return isClosing;
+	}
+
+	/**
+	 * Initializes all of the default services for the workbench. For
+	 * initializing the command-based services, this also parses the registry
+	 * and hooks up all the required listeners.
+	 */
+	private final void initializeDefaultServices() {
+		// BEGIN: some e4 services
+		e4Context.set(IWorkbenchBrowserSupport.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						return WorkbenchBrowserSupport.getInstance();
+					}
+				});
+		e4Context.set(EditorHistory.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (editorHistory == null) {
+					editorHistory = new EditorHistory();
+				}
+				return editorHistory;
+			}
+		});
+		e4Context.set(IWorkbenchHelpSystem.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						return WorkbenchHelpSystem.getInstance();
+					}
+				});
+		e4Context.set(IProgressService.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				return ProgressManager.getInstance();
+			}
+		});
+		e4Context.set(IThemeManager.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				return WorkbenchThemeManager.getInstance();
+			}
+		});
+		e4Context.set(WorkbenchIntroManager.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						if (introManager == null) {
+							introManager = new WorkbenchIntroManager(
+									Workbench.this);
+						}
+						return introManager;
+					}
+				});
+		e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_NAME,
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						IEclipseContext childContext = (IEclipseContext) context
+								.getLocal(IContextConstants.ACTIVE_CHILD);
+						if (childContext != null) {
+							return childContext
+									.get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+						}
+						return null;
+					}
+				});
+		e4Context.set(ISources.ACTIVE_ACTION_SETS_NAME, new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				IEclipseContext childContext = (IEclipseContext) context
+						.getLocal(IContextConstants.ACTIVE_CHILD);
+				if (childContext != null) {
+					return childContext.get(ISources.ACTIVE_ACTION_SETS_NAME);
+				}
+				return null;
+			}
+		});
+		e4Context.set(ISources.ACTIVE_PART_NAME, new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				IEclipseContext childContext = (IEclipseContext) context
+						.getLocal(IContextConstants.ACTIVE_CHILD);
+				if (childContext != null) {
+					return childContext.get(ISources.ACTIVE_PART_NAME);
+				}
+				return null;
+			}
+		});
+		e4Context.set(ISources.ACTIVE_SITE_NAME, new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				IEclipseContext childContext = (IEclipseContext) context
+						.getLocal(IContextConstants.ACTIVE_CHILD);
+				if (childContext != null) {
+					return childContext.get(ISources.ACTIVE_SITE_NAME);
+				}
+				return null;
+			}
+		});
+		e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_IS_COOLBAR_VISIBLE_NAME,
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						WorkbenchWindow window = (WorkbenchWindow) context
+								.get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+						return window == null ? false : window
+								.getCoolBarVisible();
+					}
+				});
+		e4Context
+				.set(ISources.ACTIVE_WORKBENCH_WINDOW_IS_PERSPECTIVEBAR_VISIBLE_NAME,
+						new ContextFunction() {
+							@Override
+							public Object compute(IEclipseContext context,
+									Object[] arguments) {
+								WorkbenchWindow window = (WorkbenchWindow) context
+										.get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+								return window == null ? false : window
+										.getPerspectiveBarVisible();
+							}
+						});
+		e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_ACTIVE_PERSPECTIVE_NAME,
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						IEclipseContext childContext = (IEclipseContext) context
+								.getLocal(IContextConstants.ACTIVE_CHILD);
+						if (childContext != null) {
+							return childContext
+									.get(ISources.ACTIVE_WORKBENCH_WINDOW_ACTIVE_PERSPECTIVE_NAME);
+						}
+						MPerspective persp = (MPerspective) context
+								.get(MPerspective.class.getName());
+						final String perspId = persp == null ? null : persp
+								.getId();
+						org.eclipse.e4.workbench.ui.internal.Activator
+								.trace(org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_CMDS,
+										"asked for perspective " + perspId, //$NON-NLS-1$
+										null);
+						return perspId;
+					}
+				});
+		// END: some e4 services
+
+		final IContributionService contributionService = new ContributionService(
+				getAdvisor());
+		serviceLocator.registerService(IContributionService.class,
+				contributionService);
+
+		// TODO Correctly order service initialization
+		// there needs to be some serious consideration given to
+		// the services, and hooking them up in the correct order
+		final IEvaluationService evaluationService = (IEvaluationService) serviceLocator
+				.getService(IEvaluationService.class);
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				serviceLocator.registerService(
+						ISaveablesLifecycleListener.class, new SaveablesList());
+			}
+		});
+
+		/*
+		 * Phase 1 of the initialization of commands. When this phase completes,
+		 * all the services and managers will exist, and be accessible via the
+		 * getService(Object) method.
+		 */
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				Command.DEBUG_COMMAND_EXECUTION = Policy.DEBUG_COMMANDS;
+				commandManager = (CommandManager) e4Context
+						.get(CommandManager.class.getName());
+			}
+		});
+
+		final CommandService[] commandService = new CommandService[1];
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				commandService[0] = new CommandService(commandManager);
+				commandService[0].readRegistry();
+				serviceLocator.registerService(ICommandService.class,
+						commandService[0]);
+
+			}
+		});
+
+		populateCommands();
+		populateActionSets();
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				ContextManager.DEBUG = Policy.DEBUG_CONTEXTS;
+				contextManager = (ContextManager) e4Context
+						.get(ContextManager.class.getName());
+			}
+		});
+
+		final IContextService contextService = new ContextService(
+				contextManager);
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				contextService.readRegistry();
+			}
+		});
+
+		EContextService ecs = (EContextService) e4Context
+				.get(EContextService.class.getName());
+		ecs.activateContext(IContextService.CONTEXT_ID_DIALOG_AND_WINDOW);
+
+		serviceLocator.registerService(IContextService.class, contextService);
+
+		final IBindingService[] bindingService = new BindingService[1];
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				BindingManager.DEBUG = Policy.DEBUG_KEY_BINDINGS;
+				bindingManager = new BindingManager(contextManager,
+						commandManager);
+				bindingService[0] = new BindingService(bindingManager,
+						commandService[0], Workbench.this);
+
+			}
+		});
+
+		bindingService[0].readRegistryAndPreferences(commandService[0]);
+		serviceLocator
+				.registerService(IBindingService.class, bindingService[0]);
+
+		final CommandImageManager commandImageManager = new CommandImageManager();
+		final CommandImageService commandImageService = new CommandImageService(
+				commandImageManager, commandService[0]);
+		commandImageService.readRegistry();
+		serviceLocator.registerService(ICommandImageService.class,
+				commandImageService);
+
+		final WorkbenchMenuService menuService = new WorkbenchMenuService(
+				serviceLocator);
+
+		serviceLocator.registerService(IMenuService.class, menuService);
+		// the service must be registered before it is initialized - its
+		// initialization uses the service locator to address a dependency on
+		// the menu service
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				menuService.readRegistry();
+			}
+		});
+
+		/*
+		 * Phase 2 of the initialization of commands. The source providers that
+		 * the workbench provides are creating and registered with the above
+		 * services. These source providers notify the services when particular
+		 * pieces of workbench state change.
+		 */
+		final SourceProviderService sourceProviderService = new SourceProviderService(
+				serviceLocator);
+		serviceLocator.registerService(ISourceProviderService.class,
+				sourceProviderService);
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				// this currently instantiates all players ... sigh
+				sourceProviderService.readRegistry();
+				ISourceProvider[] sp = sourceProviderService
+						.getSourceProviders();
+				for (int i = 0; i < sp.length; i++) {
+					evaluationService.addSourceProvider(sp[i]);
+					if (!(sp[i] instanceof ActiveContextSourceProvider)) {
+						contextService.addSourceProvider(sp[i]);
+					}
+				}
+			}
+		});
+
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				// these guys are need to provide the variables they say
+				// they source
+				actionSetSourceProvider = (ActionSetSourceProvider) sourceProviderService
+						.getSourceProvider(ISources.ACTIVE_ACTION_SETS_NAME);
+
+				FocusControlSourceProvider focusControl = (FocusControlSourceProvider) sourceProviderService
+						.getSourceProvider(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME);
+				serviceLocator.registerService(IFocusService.class,
+						focusControl);
+
+				menuSourceProvider = (MenuSourceProvider) sourceProviderService
+						.getSourceProvider(ISources.ACTIVE_MENU_NAME);
+			}
+		});
+
+		/*
+		 * Phase 3 of the initialization of commands. This handles the creation
+		 * of wrappers for legacy APIs. By the time this phase completes, any
+		 * code trying to access commands through legacy APIs should work.
+		 */
+		final IHandlerService[] handlerService = new IHandlerService[1];
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+			public void runWithException() {
+				handlerService[0] = new LegacyHandlerService(e4Context);
+				handlerService[0].readRegistry();
+			}
+		});
+		serviceLocator
+				.registerService(IHandlerService.class, handlerService[0]);
+		// BEGIN: e4 services
+		e4Context.set(IWorkbenchContextSupport.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						if (workbenchContextSupport == null) {
+							workbenchContextSupport = new WorkbenchContextSupport(
+									Workbench.this, contextManager);
+						}
+						return workbenchContextSupport;
+					}
+				});
+		e4Context.set(IWorkbenchCommandSupport.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						if (workbenchCommandSupport == null) {
+							workbenchCommandSupport = new WorkbenchCommandSupport(
+									bindingManager, commandManager,
+									contextManager, handlerService[0]);
+						}
+						return workbenchCommandSupport;
+					}
+				});
+
+		// TODO needs a replacement with the updated binding service and bridge
+		// EBindingService e4BindingService = new EBindingService() {
+		// public TriggerSequence getBestActiveBindingFor(
+		// ParameterizedCommand command) {
+		// if (bindingService[0] == null)
+		// return null;
+		// return bindingService[0].getBestActiveBindingFor(command);
+		// }
+		// };
+		// e4Context.set(EBindingService.class.getName(), e4BindingService);
+
+		final ISourceProvider showInProvider = sourceProviderService
+				.getSourceProvider(ISources.SHOW_IN_SELECTION);
+		showInProvider.addSourceProviderListener(getSourceListener());
+		final ISourceProvider focusProvider = sourceProviderService
+				.getSourceProvider(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME);
+		focusProvider.addSourceProviderListener(getSourceListener());
+		// END: e4 services
+
+		initializeCommandResolver();
+
+		addWindowListener(windowListener);
+		bindingManager.addBindingManagerListener(bindingManagerListener);
+
+		serviceLocator.registerService(ISelectionConversionService.class,
+				new SelectionConversionService());
+	}
+
+	private ISourceProviderListener getSourceListener() {
+		if (sourceListener == null) {
+			sourceListener = new ISourceProviderListener() {
+				public void sourceChanged(int sourcePriority,
+						String sourceName, Object sourceValue) {
+					updateChangedVariable(sourceName, sourceValue);
+				}
+
+				public void sourceChanged(int sourcePriority,
+						Map sourceValuesByName) {
+					final Iterator i = sourceValuesByName.entrySet().iterator();
+					while (i.hasNext()) {
+						Map.Entry entry = (Map.Entry) i.next();
+						sourceChanged(0, (String) entry.getKey(),
+								entry.getValue());
+					}
+				}
+			};
+		}
+		return sourceListener;
+	}
+
+	void updateChangedVariable(String sourceName, Object sourceValue) {
+		boolean updated = updateVariable(ISources.SHOW_IN_INPUT, sourceName,
+				sourceValue);
+		if (!updated) {
+			updated = updateVariable(ISources.SHOW_IN_SELECTION, sourceName,
+					sourceValue);
+		}
+		if (!updated) {
+			updated = updateVariable(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME,
+					sourceName, sourceValue);
+		}
+		if (!updated) {
+			updated = updateVariable(ISources.ACTIVE_FOCUS_CONTROL_NAME,
+					sourceName, sourceValue);
+		}
+		if (!updated) {
+			updated = updateVariable(ISources.ACTIVE_SHELL_NAME, sourceName,
+					sourceValue);
+			if (updated) {
+				org.eclipse.e4.workbench.ui.internal.Activator
+						.trace(org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_WORKBENCH,
+								"activated shell: " + sourceValue, null); //$NON-NLS-1$
+				if (sourceValue instanceof Shell) {
+					activateShell((Shell) sourceValue);
+				}
+			}
+		}
+	}
+
+	boolean updateVariable(String name, String sourceName, Object sourceValue) {
+		if (name.equals(sourceName)) {
+			if (sourceValue == null
+					|| sourceValue == IEvaluationContext.UNDEFINED_VARIABLE) {
+				e4Context.remove(name);
+			} else {
+				e4Context.set(name, sourceValue);
+			}
+			return true;
+		}
+		return false;
+	}
+
+	void activateShell(final Shell shell) {
+		if (shell.getParent() instanceof Shell) {
+			final String localContext = "localContext"; //$NON-NLS-1$
+			Object obj = shell.getData(localContext);
+			if (obj instanceof IEclipseContext) {
+				e4Context.set(IContextConstants.ACTIVE_CHILD, obj);
+			} else {
+				final IEclipseContext shellContext = EclipseContextFactory
+						.create(e4Context, UISchedulerStrategy.getInstance());
+				shellContext.set(IContextConstants.DEBUG_STRING,
+						"Shell Context (" + shell + ")"); //$NON-NLS-1$//$NON-NLS-2$
+				shell.setData(localContext, shellContext);
+				e4Context.set(IContextConstants.ACTIVE_CHILD, shellContext);
+				shell.addDisposeListener(new DisposeListener() {
+					public void widgetDisposed(DisposeEvent e) {
+						shell.setData(localContext, null);
+						if (shellContext instanceof org.eclipse.e4.core.services.IDisposable) {
+							((org.eclipse.e4.core.services.IDisposable) shellContext)
+									.dispose();
+						}
+					}
+				});
+			}
+		} else {
+			if (shell.getData() instanceof WorkbenchWindow) {
+				e4Context.set(IContextConstants.ACTIVE_CHILD,
+						((WorkbenchWindow) shell.getData()).getModelWindow()
+								.getContext());
+			}
+		}
+	}
+
+	static class MakeHandlersGo extends AbstractHandler {
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands
+		 * .ExecutionEvent)
+		 */
+		public Object execute(ExecutionEvent event) throws ExecutionException {
+			org.eclipse.e4.workbench.ui.internal.Activator.trace(
+					org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_CMDS,
+					"AllHandlerGo: not for executing", null); //$NON-NLS-1$
+			return null;
+		}
+
+	}
+
+	protected void populateCommands() {
+		MakeHandlersGo allHandlers = new MakeHandlersGo();
+		if (allHandlers != null)
+			return;
+		ECommandService cs = (ECommandService) e4Context
+				.get(ECommandService.class.getName());
+		MApplication app = (MApplication) e4Context.get(MApplication.class
+				.getName());
+		Command[] cmds = commandManager.getAllCommands();
+		for (int i = 0; i < cmds.length; i++) {
+			Command cmd = cmds[i];
+			final String cmdId = cmd.getId();
+			if (cmdId.contains("(")) { //$NON-NLS-1$
+				org.eclipse.e4.workbench.ui.internal.Activator.trace(
+						org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_CMDS,
+						"Invalid command: " + cmd, null); //$NON-NLS-1$
+				continue;
+			}
+			cmd.setHandler(allHandlers);
+			cs.getCommand(cmdId);
+			MCommand mcmd = MApplicationFactory.eINSTANCE.createCommand();
+			mcmd.setId(cmdId);
+			try {
+				mcmd.setCommandName(cmd.getName());
+			} catch (NotDefinedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			app.getCommands().add(mcmd);
+		}
+	}
+
+	// TBD update to use #addCommand()
+	protected void populateActionSets() {
+		String hack = ""; //$NON-NLS-1$
+		if (hack.length() == 0)
+			return;
+
+		ECommandService cs = (ECommandService) e4Context
+				.get(ECommandService.class.getName());
+		Category category = cs
+				.getCategory(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+		category.define("Action Sets", null); //$NON-NLS-1$
+		MApplication app = (MApplication) e4Context.get(MApplication.class
+				.getName());
+		IConfigurationElement[] actionSetElements = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+		for (IConfigurationElement ase : actionSetElements) {
+			IConfigurationElement[] elements = ase
+					.getChildren(IWorkbenchRegistryConstants.TAG_ACTION);
+
+			for (IConfigurationElement element : elements) {
+				String id = MenuHelper.getActionSetCommandId(element);
+				if (id != null
+						&& id.startsWith(MenuHelper.ACTION_SET_CMD_PREFIX)) {
+					MCommand mcmd = MApplicationFactory.eINSTANCE
+							.createCommand();
+					mcmd.setId(id);
+					mcmd.setCommandName(LegacyActionTools
+							.removeMnemonics(MenuHelper.getLabel(element)));
+					app.getCommands().add(mcmd);
+					Command command = cs.getCommand(id);
+					if (!command.isDefined()) {
+						command.define(mcmd.getCommandName(), null, category);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns true if the Workbench is in the process of starting.
+	 * 
+	 * @return <code>true</code> if the Workbench is starting, but not yet
+	 *         running the event loop.
+	 */
+	public boolean isStarting() {
+		return isStarting && isRunning();
+	}
+
+	/*
+	 * Creates a new workbench window.
+	 * 
+	 * @return the new workbench window
+	 */
+	private WorkbenchWindow newWorkbenchWindow() {
+		WorkbenchWindow wbw = ((WorkbenchImplementation) Tweaklets
+				.get(WorkbenchImplementation.KEY))
+				.createWorkbenchWindow(getNewWindowNumber());
+		return wbw;
+	}
+
+	/*
+	 * If a perspective was specified on the command line (-perspective) then
+	 * force that perspective to open in the active window.
+	 */
+	private void forceOpenPerspective() {
+		if (getWorkbenchWindowCount() == 0) {
+			// there should be an open window by now, bail out.
+			return;
+		}
+
+		String perspId = null;
+		String[] commandLineArgs = Platform.getCommandLineArgs();
+		for (int i = 0; i < commandLineArgs.length - 1; i++) {
+			if (commandLineArgs[i].equalsIgnoreCase("-perspective")) { //$NON-NLS-1$
+				perspId = commandLineArgs[i + 1];
+				break;
+			}
+		}
+		if (perspId == null) {
+			return;
+		}
+		IPerspectiveDescriptor desc = getPerspectiveRegistry()
+				.findPerspectiveWithId(perspId);
+		if (desc == null) {
+			return;
+		}
+
+		IWorkbenchWindow win = getActiveWorkbenchWindow();
+		if (win == null) {
+			win = getWorkbenchWindows()[0];
+		}
+
+		final String threadPerspId = perspId;
+		final IWorkbenchWindow threadWin = win;
+		StartupThreading.runWithoutExceptions(new StartupRunnable() {
+			public void runWithException() throws Throwable {
+				try {
+					showPerspective(threadPerspId, threadWin);
+				} catch (WorkbenchException e) {
+					String msg = "Workbench exception showing specified command line perspective on startup."; //$NON-NLS-1$
+					WorkbenchPlugin.log(msg, new Status(IStatus.ERROR,
+							PlatformUI.PLUGIN_ID, 0, msg, e));
+				}
+			}
+		});
+	}
+
+	/**
+	 * Opens the initial workbench window.
+	 */
+	/* package */void openFirstTimeWindow() {
+		final boolean showProgress = PrefUtil.getAPIPreferenceStore()
+				.getBoolean(
+						IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP);
+
+		if (!showProgress) {
+			doOpenFirstTimeWindow();
+		} else {
+			// We don't know how many plug-ins will be loaded,
+			// assume we are loading a tenth of the installed plug-ins.
+			// (The Eclipse SDK loads 7 of 86 plug-ins at startup as of
+			// 2005-5-20)
+			final int expectedProgressCount = Math.max(1, WorkbenchPlugin
+					.getDefault().getBundleCount() / 10);
+
+			runStartupWithProgress(expectedProgressCount, new Runnable() {
+				public void run() {
+					doOpenFirstTimeWindow();
+				}
+			});
+		}
+	}
+
+	private void runStartupWithProgress(final int expectedProgressCount,
+			final Runnable runnable) {
+		progressCount = 0;
+		final double cutoff = 0.95;
+
+		AbstractSplashHandler handler = getSplash();
+		IProgressMonitor progressMonitor = null;
+		if (handler != null)
+			progressMonitor = handler.getBundleProgressMonitor();
+
+		if (progressMonitor == null) {
+			// cannot report progress (e.g. if the splash screen is not showing)
+			// fall back to starting without showing progress.
+			runnable.run();
+		} else {
+			progressMonitor.beginTask("", expectedProgressCount); //$NON-NLS-1$
+			SynchronousBundleListener bundleListener = new StartupProgressBundleListener(
+					progressMonitor, (int) (expectedProgressCount * cutoff));
+			WorkbenchPlugin.getDefault().addBundleListener(bundleListener);
+			try {
+				runnable.run();
+				progressMonitor.subTask(WorkbenchMessages.Startup_Done);
+				int remainingWork = expectedProgressCount
+						- Math.min(progressCount,
+								(int) (expectedProgressCount * cutoff));
+				progressMonitor.worked(remainingWork);
+				progressMonitor.done();
+			} finally {
+				WorkbenchPlugin.getDefault().removeBundleListener(
+						bundleListener);
+			}
+		}
+	}
+
+	private void doOpenFirstTimeWindow() {
+		try {
+			final IAdaptable input[] = new IAdaptable[1];
+			StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+				public void runWithException() throws Throwable {
+					input[0] = getDefaultPageInput();
+				}
+			});
+
+			busyOpenWorkbenchWindow(getPerspectiveRegistry()
+					.getDefaultPerspective(), input[0]);
+		} catch (final WorkbenchException e) {
+			// Don't use the window's shell as the dialog parent,
+			// as the window is not open yet (bug 76724).
+			StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+				public void runWithException() throws Throwable {
+					ErrorDialog.openError(null,
+							WorkbenchMessages.Problems_Opening_Page,
+							e.getMessage(), e.getStatus());
+				}
+			});
+		}
+	}
+
+	/*
+	 * Restores the workbench UI from the workbench state file (workbench.xml).
+	 * 
+	 * @return a status object indicating OK if a window was opened,
+	 * RESTORE_CODE_RESET if no window was opened but one should be, and
+	 * RESTORE_CODE_EXIT if the workbench should close immediately
+	 */
+	/* package */IStatus restoreState() {
+		// TBD the Save/Restore functionality is not implemented
+		String msg = WorkbenchMessages.Workbench_restoreDisabled;
+		return new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH,
+				IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkbenchWindow openWorkbenchWindow(IAdaptable input)
+			throws WorkbenchException {
+		return openWorkbenchWindow(getPerspectiveRegistry()
+				.getDefaultPerspective(), input);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkbenchWindow openWorkbenchWindow(final String perspID,
+			final IAdaptable input) throws WorkbenchException {
+		// Run op in busy cursor.
+		final Object[] result = new Object[1];
+		BusyIndicator.showWhile(null, new Runnable() {
+			public void run() {
+				try {
+					result[0] = busyOpenWorkbenchWindow(perspID, input);
+				} catch (WorkbenchException e) {
+					result[0] = e;
+				}
+			}
+		});
+		if (result[0] instanceof IWorkbenchWindow) {
+			return (IWorkbenchWindow) result[0];
+		} else if (result[0] instanceof WorkbenchException) {
+			throw (WorkbenchException) result[0];
+		} else {
+			throw new WorkbenchException(
+					WorkbenchMessages.Abnormal_Workbench_Conditi);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbench#restoreWorkbenchWindow(org.eclipse.ui.IMemento)
+	 */
+	IWorkbenchWindow restoreWorkbenchWindow(IMemento memento)
+			throws WorkbenchException {
+		WorkbenchWindow newWindow = newWorkbenchWindow();
+		newWindow.create();
+
+		windowManager.add(newWindow);
+
+		// whether the window was opened
+		boolean opened = false;
+
+		try {
+			newWindow.restoreState(memento, null);
+			newWindow.fireWindowRestored();
+			newWindow.open();
+			opened = true;
+		} finally {
+			if (!opened) {
+				newWindow.close();
+			}
+		}
+
+		return newWindow;
+	}
+
+	/*
+	 * Record the workbench UI in a document
+	 */
+	private XMLMemento recordWorkbenchState() {
+		XMLMemento memento = XMLMemento
+				.createWriteRoot(IWorkbenchConstants.TAG_WORKBENCH);
+		final IStatus status = saveState(memento);
+		if (status.getSeverity() != IStatus.OK) {
+			// don't use newWindow as parent because it has not yet been opened
+			// (bug 76724)
+			StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+				public void runWithException() throws Throwable {
+					ErrorDialog.openError(null,
+							WorkbenchMessages.Workbench_problemsSaving,
+							WorkbenchMessages.Workbench_problemsSavingMsg,
+							status);
+				}
+			});
+
+		}
+		return memento;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public boolean restart() {
+		// this is the return code from run() to trigger a restart
+		return close(PlatformUI.RETURN_RESTART, false);
+	}
+
+	/**
+	 * Returns the ids of all plug-ins that extend the
+	 * <code>org.eclipse.ui.startup</code> extension point.
+	 * 
+	 * @return the ids of all plug-ins containing 1 or more startup extensions
+	 */
+	public String[] getEarlyActivatedPlugins() {
+		IExtensionPoint point = Platform.getExtensionRegistry()
+				.getExtensionPoint(PlatformUI.PLUGIN_ID,
+						IWorkbenchRegistryConstants.PL_STARTUP);
+		IExtension[] extensions = point.getExtensions();
+		ArrayList pluginIds = new ArrayList(extensions.length);
+		for (int i = 0; i < extensions.length; i++) {
+			String id = extensions[i].getNamespace();
+			if (!pluginIds.contains(id)) {
+				pluginIds.add(id);
+			}
+		}
+		return (String[]) pluginIds.toArray(new String[pluginIds.size()]);
+	}
+
+	/**
+	 * Returns the ids of the early activated plug-ins that have been disabled
+	 * by the user.
+	 * 
+	 * @return the ids of the early activated plug-ins that have been disabled
+	 *         by the user
+	 */
+	public String[] getDisabledEarlyActivatedPlugins() {
+		String pref = PrefUtil.getInternalPreferenceStore().getString(
+				IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
+		return Util.getArrayFromList(pref, ";"); //$NON-NLS-1$
+	}
+
+	/*
+	 * Starts all plugins that extend the <code> org.eclipse.ui.startup </code>
+	 * extension point, and that the user has not disabled via the preference
+	 * page.
+	 */
+	private void startPlugins() {
+		IExtensionRegistry registry = Platform.getExtensionRegistry();
+
+		// bug 55901: don't use getConfigElements directly, for pre-3.0
+		// compat, make sure to allow both missing class
+		// attribute and a missing startup element
+		IExtensionPoint point = registry.getExtensionPoint(
+				PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_STARTUP);
+
+		final IExtension[] extensions = point.getExtensions();
+		if (extensions.length == 0) {
+			return;
+		}
+		Job job = new Job("Workbench early startup") { //$NON-NLS-1$
+			protected IStatus run(IProgressMonitor monitor) {
+				HashSet disabledPlugins = new HashSet(
+						Arrays.asList(getDisabledEarlyActivatedPlugins()));
+				monitor.beginTask(WorkbenchMessages.Workbench_startingPlugins,
+						extensions.length);
+				for (int i = 0; i < extensions.length; ++i) {
+					if (monitor.isCanceled() || !isRunning()) {
+						return Status.CANCEL_STATUS;
+					}
+					IExtension extension = extensions[i];
+
+					// if the plugin is not in the set of disabled plugins, then
+					// execute the code to start it
+					if (!disabledPlugins.contains(extension.getNamespace())) {
+						monitor.subTask(extension.getNamespace());
+						SafeRunner.run(new EarlyStartupRunnable(extension));
+					}
+					monitor.worked(1);
+				}
+				monitor.done();
+				return Status.OK_STATUS;
+			}
+
+			public boolean belongsTo(Object family) {
+				return EARLY_STARTUP_FAMILY.equals(family);
+			}
+		};
+		job.setSystem(true);
+		job.schedule();
+	}
+
+	/**
+	 * Internal method for running the workbench UI. This entails processing and
+	 * dispatching events until the workbench is closed or restarted.
+	 * 
+	 * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
+	 *         exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
+	 *         workbench was terminated with a call to
+	 *         {@link IWorkbench#restart IWorkbench.restart};
+	 *         {@link PlatformUI#RETURN_UNSTARTABLE RETURN_UNSTARTABLE}if the
+	 *         workbench could not be started; other values reserved for future
+	 *         use
+	 * @since 3.0
+	 */
+	private int runUI() {
+		UIStats.start(UIStats.START_WORKBENCH, "Workbench"); //$NON-NLS-1$
+
+		// deadlock code
+		boolean avoidDeadlock = true;
+
+		String[] commandLineArgs = Platform.getCommandLineArgs();
+		for (int i = 0; i < commandLineArgs.length; i++) {
+			if (commandLineArgs[i].equalsIgnoreCase("-allowDeadlock")) { //$NON-NLS-1$
+				avoidDeadlock = false;
+			}
+		}
+
+		final UISynchronizer synchronizer;
+
+		if (avoidDeadlock) {
+			UILockListener uiLockListener = new UILockListener(display);
+			Job.getJobManager().setLockListener(uiLockListener);
+			synchronizer = new UISynchronizer(display, uiLockListener);
+			display.setSynchronizer(synchronizer);
+			// declare the main thread to be a startup thread.
+			UISynchronizer.startupThread.set(Boolean.TRUE);
+		} else
+			synchronizer = null;
+
+		// prime the splash nice and early
+		if (createSplash)
+			createSplashWrapper();
+
+		// ModalContext should not spin the event loop (there is no UI yet to
+		// block)
+		ModalContext.setAllowReadAndDispatch(false);
+
+		// if the -debug command line argument is used and the event loop is
+		// being
+		// run while starting the Workbench, log a warning.
+		if (WorkbenchPlugin.getDefault().isDebugging()) {
+			display.asyncExec(new Runnable() {
+				public void run() {
+					if (isStarting()) {
+						WorkbenchPlugin.log(StatusUtil
+								.newStatus(
+										IStatus.WARNING,
+										"Event loop should not be run while the Workbench is starting.", //$NON-NLS-1$
+										new RuntimeException()));
+					}
+				}
+			});
+		}
+
+		Listener closeListener = new Listener() {
+			public void handleEvent(Event event) {
+				event.doit = close();
+			}
+		};
+
+		// Initialize an exception handler.
+		Window.IExceptionHandler handler = ExceptionHandler.getInstance();
+
+		try {
+			// react to display close event by closing workbench nicely
+			display.addListener(SWT.Close, closeListener);
+
+			// install backstop to catch exceptions thrown out of event loop
+			Window.setExceptionHandler(handler);
+
+			final boolean[] initOK = new boolean[1];
+
+			if (getSplash() != null) {
+
+				final boolean[] initDone = new boolean[] { false };
+				final Throwable[] error = new Throwable[1];
+				Thread initThread = new Thread() {
+					/*
+					 * (non-Javadoc)
+					 * 
+					 * @see java.lang.Thread#run()
+					 */
+					public void run() {
+						try {
+							// declare us to be a startup thread so that our
+							// syncs will be executed
+							UISynchronizer.startupThread.set(Boolean.TRUE);
+							initOK[0] = Workbench.this.init();
+						} catch (Throwable e) {
+							error[0] = e;
+						} finally {
+							initDone[0] = true;
+							display.wake();
+						}
+					}
+				};
+				initThread.start();
+				while (true) {
+					if (!display.readAndDispatch()) {
+						if (initDone[0])
+							break;
+						display.sleep();
+					}
+				}
+				Throwable throwable = error[0];
+				if (throwable != null) {
+					if (throwable instanceof Error)
+						throw (Error) throwable;
+					if (throwable instanceof Exception)
+						throw (Exception) throwable;
+
+					// how very exotic - something that isn't playing by the
+					// rules. Wrap it in an error and bail
+					throw new Error(throwable);
+				}
+			} else {
+				// initialize workbench and restore or open one window
+				initOK[0] = init();
+
+			}
+			// drop the splash screen now that a workbench window is up
+			Platform.endSplash();
+
+			// let the advisor run its start up code
+			if (initOK[0]) {
+				advisor.postStartup(); // may trigger a close/restart
+			}
+
+			if (initOK[0] && runEventLoop) {
+				// start eager plug-ins
+				startPlugins();
+				addStartupRegistryListener();
+
+				// WWinPluginAction.refreshActionList();
+
+				display.asyncExec(new Runnable() {
+					public void run() {
+						UIStats.end(UIStats.START_WORKBENCH, this, "Workbench"); //$NON-NLS-1$
+						UIStats.startupComplete();
+					}
+				});
+
+				getWorkbenchTestable().init(display, this);
+
+				// allow ModalContext to spin the event loop
+				ModalContext.setAllowReadAndDispatch(true);
+				isStarting = false;
+
+				if (synchronizer != null)
+					synchronizer.started();
+				// the event loop
+				runEventLoop(handler, display);
+			}
+
+		} catch (final Exception e) {
+			if (!display.isDisposed()) {
+				handler.handleException(e);
+			} else {
+				String msg = "Exception in Workbench.runUI after display was disposed"; //$NON-NLS-1$
+				WorkbenchPlugin.log(msg, new Status(IStatus.ERROR,
+						WorkbenchPlugin.PI_WORKBENCH, 1, msg, e));
+			}
+		} finally {
+			// mandatory clean up
+
+			// The runEventLoop flag may not have been cleared if an exception
+			// occurred
+			// Needs to be false to ensure PlatformUI.isWorkbenchRunning()
+			// returns false.
+			runEventLoop = false;
+
+			if (!display.isDisposed()) {
+				display.removeListener(SWT.Close, closeListener);
+			}
+		}
+
+		// restart or exit based on returnCode
+		return returnCode;
+	}
+
+	/*
+	 * Runs an event loop for the workbench.
+	 */
+	private void runEventLoop(Window.IExceptionHandler handler, Display display) {
+		runEventLoop = true;
+		while (runEventLoop) {
+			try {
+				if (!display.readAndDispatch()) {
+					getAdvisor().eventLoopIdle(display);
+				}
+			} catch (Throwable t) {
+				handler.handleException(t);
+				// In case Display was closed under us
+				if (display.isDisposed())
+					runEventLoop = false;
+			}
+		}
+	}
+
+	/*
+	 * Saves the current state of the workbench so it can be restored later on
+	 */
+	private IStatus saveState(IMemento memento) {
+		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+				WorkbenchMessages.Workbench_problemsSaving, null);
+
+		// Save the version number.
+		memento.putString(IWorkbenchConstants.TAG_VERSION, VERSION_STRING[1]);
+
+		// Save how many plug-ins were loaded while restoring the workbench
+		if (progressCount != -1) {
+			memento.putInteger(IWorkbenchConstants.TAG_PROGRESS_COUNT,
+					progressCount);
+		}
+
+		// Save the advisor state.
+		IMemento advisorState = memento
+				.createChild(IWorkbenchConstants.TAG_WORKBENCH_ADVISOR);
+		result.add(getAdvisor().saveState(advisorState));
+
+		// Save the workbench windows.
+		IWorkbenchWindow[] windows = getWorkbenchWindows();
+		for (int nX = 0; nX < windows.length; nX++) {
+			WorkbenchWindow window = (WorkbenchWindow) windows[nX];
+			IMemento childMem = memento
+					.createChild(IWorkbenchConstants.TAG_WINDOW);
+			result.merge(window.saveState(childMem));
+		}
+		result.add(getEditorHistory().saveState(
+				memento.createChild(IWorkbenchConstants.TAG_MRU_LIST)));
+		return result;
+	}
+
+	/*
+	 * Save the workbench UI in a persistence file.
+	 */
+	private boolean saveMementoToFile(XMLMemento memento) {
+		// Save it to a file.
+		// XXX: nobody currently checks the return value of this method.
+		File stateFile = getWorkbenchStateFile();
+		if (stateFile == null) {
+			return false;
+		}
+		try {
+			FileOutputStream stream = new FileOutputStream(stateFile);
+			OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
+			memento.save(writer);
+			writer.close();
+		} catch (IOException e) {
+			stateFile.delete();
+			MessageDialog.openError((Shell) null,
+					WorkbenchMessages.SavingProblem,
+					WorkbenchMessages.ProblemSavingState);
+			return false;
+		}
+
+		// Success !
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkbenchPage showPerspective(String perspectiveId,
+			IWorkbenchWindow window) throws WorkbenchException {
+		Assert.isNotNull(perspectiveId);
+
+		// If the specified window has the requested perspective open, then the
+		// window
+		// is given focus and the perspective is shown. The page's input is
+		// ignored.
+		WorkbenchWindow win = (WorkbenchWindow) window;
+		if (win != null) {
+			WorkbenchPage page = win.getActiveWorkbenchPage();
+			if (page != null) {
+				IPerspectiveDescriptor perspectives[] = page
+						.getOpenPerspectives();
+				for (int i = 0; i < perspectives.length; i++) {
+					IPerspectiveDescriptor persp = perspectives[i];
+					if (perspectiveId.equals(persp.getId())) {
+						win.makeVisible();
+						page.setPerspective(persp);
+						return page;
+					}
+				}
+			}
+		}
+
+		// If another window that has the workspace root as input and the
+		// requested
+		// perpective open and active, then the window is given focus.
+		IAdaptable input = getDefaultPageInput();
+		IWorkbenchWindow[] windows = getWorkbenchWindows();
+		for (int i = 0; i < windows.length; i++) {
+			win = (WorkbenchWindow) windows[i];
+			if (window != win) {
+				WorkbenchPage page = win.getActiveWorkbenchPage();
+				if (page != null) {
+					boolean inputSame = false;
+					if (input == null) {
+						inputSame = (page.getInput() == null);
+					} else {
+						inputSame = input.equals(page.getInput());
+					}
+					if (inputSame) {
+						Perspective persp = page.getActivePerspective();
+						if (persp != null) {
+							IPerspectiveDescriptor desc = persp.getDesc();
+							if (desc != null) {
+								if (perspectiveId.equals(desc.getId())) {
+									Shell shell = win.getShell();
+									shell.open();
+									if (shell.getMinimized()) {
+										shell.setMinimized(false);
+									}
+									return page;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+
+		// Otherwise the requested perspective is opened and shown in the
+		// specified
+		// window or in a new window depending on the current user preference
+		// for opening
+		// perspectives, and that window is given focus.
+		win = (WorkbenchWindow) window;
+		if (win != null) {
+			IPreferenceStore store = WorkbenchPlugin.getDefault()
+					.getPreferenceStore();
+			int mode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE);
+			IWorkbenchPage page = win.getActiveWorkbenchPage();
+			IPerspectiveDescriptor persp = null;
+			if (page != null) {
+				persp = page.getPerspective();
+			}
+
+			// Only open a new window if user preference is set and the window
+			// has an active perspective.
+			if (IPreferenceConstants.OPM_NEW_WINDOW == mode && persp != null) {
+				IWorkbenchWindow newWindow = openWorkbenchWindow(perspectiveId,
+						input);
+				return newWindow.getActivePage();
+			}
+
+			IPerspectiveDescriptor desc = getPerspectiveRegistry()
+					.findPerspectiveWithId(perspectiveId);
+			if (desc == null) {
+				throw new WorkbenchException(
+						NLS.bind(
+								WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+								perspectiveId));
+			}
+			win.getShell().open();
+			if (page == null) {
+				page = win.openPage(perspectiveId, input);
+			} else {
+				page.setPerspective(desc);
+			}
+			return page;
+		}
+
+		// Just throw an exception....
+		throw new WorkbenchException(
+				NLS.bind(WorkbenchMessages.Workbench_showPerspectiveError,
+						perspectiveId));
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IWorkbenchPage showPerspective(String perspectiveId,
+			IWorkbenchWindow window, IAdaptable input)
+			throws WorkbenchException {
+		Assert.isNotNull(perspectiveId);
+
+		// If the specified window has the requested perspective open and the
+		// same requested
+		// input, then the window is given focus and the perspective is shown.
+		boolean inputSameAsWindow = false;
+		WorkbenchWindow win = (WorkbenchWindow) window;
+		if (win != null) {
+			WorkbenchPage page = win.getActiveWorkbenchPage();
+			if (page != null) {
+				boolean inputSame = false;
+				if (input == null) {
+					inputSame = (page.getInput() == null);
+				} else {
+					inputSame = input.equals(page.getInput());
+				}
+				if (inputSame) {
+					inputSameAsWindow = true;
+					IPerspectiveDescriptor perspectives[] = page
+							.getOpenPerspectives();
+					for (int i = 0; i < perspectives.length; i++) {
+						IPerspectiveDescriptor persp = perspectives[i];
+						if (perspectiveId.equals(persp.getId())) {
+							win.makeVisible();
+							page.setPerspective(persp);
+							return page;
+						}
+					}
+				}
+			}
+		}
+
+		// If another window has the requested input and the requested
+		// perpective open and active, then that window is given focus.
+		IWorkbenchWindow[] windows = getWorkbenchWindows();
+		for (int i = 0; i < windows.length; i++) {
+			win = (WorkbenchWindow) windows[i];
+			if (window != win) {
+				WorkbenchPage page = win.getActiveWorkbenchPage();
+				if (page != null) {
+					boolean inputSame = false;
+					if (input == null) {
+						inputSame = (page.getInput() == null);
+					} else {
+						inputSame = input.equals(page.getInput());
+					}
+					if (inputSame) {
+						Perspective persp = page.getActivePerspective();
+						if (persp != null) {
+							IPerspectiveDescriptor desc = persp.getDesc();
+							if (desc != null) {
+								if (perspectiveId.equals(desc.getId())) {
+									win.getShell().open();
+									return page;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+
+		// If the specified window has the same requested input but not the
+		// requested
+		// perspective, then the window is given focus and the perspective is
+		// opened and shown
+		// on condition that the user preference is not to open perspectives in
+		// a new window.
+		win = (WorkbenchWindow) window;
+		if (inputSameAsWindow && win != null) {
+			IPreferenceStore store = WorkbenchPlugin.getDefault()
+					.getPreferenceStore();
+			int mode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE);
+
+			if (IPreferenceConstants.OPM_NEW_WINDOW != mode) {
+				IWorkbenchPage page = win.getActiveWorkbenchPage();
+				IPerspectiveDescriptor desc = getPerspectiveRegistry()
+						.findPerspectiveWithId(perspectiveId);
+				if (desc == null) {
+					throw new WorkbenchException(
+							NLS.bind(
+									WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+									perspectiveId));
+				}
+				win.getShell().open();
+				if (page == null) {
+					page = win.openPage(perspectiveId, input);
+				} else {
+					page.setPerspective(desc);
+				}
+				return page;
+			}
+		}
+
+		// If the specified window has no active perspective, then open the
+		// requested perspective and show the specified window.
+		if (win != null) {
+			IWorkbenchPage page = win.getActiveWorkbenchPage();
+			IPerspectiveDescriptor persp = null;
+			if (page != null) {
+				persp = page.getPerspective();
+			}
+			if (persp == null) {
+				IPerspectiveDescriptor desc = getPerspectiveRegistry()
+						.findPerspectiveWithId(perspectiveId);
+				if (desc == null) {
+					throw new WorkbenchException(
+							NLS.bind(
+									WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+									perspectiveId));
+				}
+				win.getShell().open();
+				if (page == null) {
+					page = win.openPage(perspectiveId, input);
+				} else {
+					page.setPerspective(desc);
+				}
+				return page;
+			}
+		}
+
+		// Otherwise the requested perspective is opened and shown in a new
+		// window, and the
+		// window is given focus.
+		IWorkbenchWindow newWindow = openWorkbenchWindow(perspectiveId, input);
+		return newWindow.getActivePage();
+	}
+
+	/*
+	 * Shuts down the application.
+	 */
+	private void shutdown() {
+		// shutdown application-specific portions first
+		try {
+			advisor.postShutdown();
+		} catch (Exception ex) {
+			StatusManager.getManager().handle(
+					StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
+							"Exceptions during shutdown", ex)); //$NON-NLS-1$
+		}
+
+		// notify regular workbench clients of shutdown, and clear the list when
+		// done
+		firePostShutdown();
+		workbenchListeners.clear();
+
+		cancelEarlyStartup();
+
+		// for dynamic UI
+		Platform.getExtensionRegistry().removeRegistryChangeListener(
+				extensionEventHandler);
+		Platform.getExtensionRegistry().removeRegistryChangeListener(
+				startupRegistryListener);
+
+		((GrabFocus) Tweaklets.get(GrabFocus.KEY)).dispose();
+
+		// Bring down all of the services.
+		serviceLocator.dispose();
+
+		workbenchActivitySupport.dispose();
+		WorkbenchHelpSystem.disposeIfNecessary();
+
+		// shutdown the rest of the workbench
+		WorkbenchColors.shutdown();
+		activityHelper.shutdown();
+		uninitializeImages();
+		if (WorkbenchPlugin.getDefault() != null) {
+			WorkbenchPlugin.getDefault().reset();
+		}
+		WorkbenchThemeManager.getInstance().dispose();
+		PropertyPageContributorManager.getManager().dispose();
+		ObjectActionContributorManager.getManager().dispose();
+		if (tracker != null) {
+			tracker.close();
+		}
+	}
+
+	/**
+	 * Cancels the early startup job, if it's still running.
+	 */
+	private void cancelEarlyStartup() {
+		Job.getJobManager().cancel(EARLY_STARTUP_FAMILY);
+		// We do not currently wait for any plug-in currently being started to
+		// complete
+		// (e.g. by doing a join on EARLY_STARTUP_FAMILY), since they may do a
+		// syncExec,
+		// which would hang. See bug 94537 for rationale.
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public IDecoratorManager getDecoratorManager() {
+		return WorkbenchPlugin.getDefault().getDecoratorManager();
+	}
+
+	/*
+	 * Returns the workbench window which was last known being the active one,
+	 * or <code> null </code> .
+	 */
+	private WorkbenchWindow getActivatedWindow() {
+		if (activatedWindow != null) {
+			Shell shell = activatedWindow.getShell();
+			if (shell != null && !shell.isDisposed()) {
+				return activatedWindow;
+			}
+		}
+
+		return null;
+	}
+
+	/*
+	 * Sets the workbench window which was last known being the active one, or
+	 * <code> null </code> .
+	 */
+	/* package */
+	void setActivatedWindow(WorkbenchWindow window) {
+		activatedWindow = window;
+	}
+
+	/**
+	 * Returns the unique object that applications use to configure the
+	 * workbench.
+	 * <p>
+	 * IMPORTANT This method is declared package-private to prevent regular
+	 * plug-ins from downcasting IWorkbench to Workbench and getting hold of the
+	 * workbench configurer that would allow them to tamper with the workbench.
+	 * The workbench configurer is available only to the application.
+	 * </p>
+	 */
+	/* package */
+	WorkbenchConfigurer getWorkbenchConfigurer() {
+		if (workbenchConfigurer == null) {
+			workbenchConfigurer = new WorkbenchConfigurer();
+		}
+		return workbenchConfigurer;
+	}
+
+	/**
+	 * Returns the workbench advisor that created this workbench.
+	 * <p>
+	 * IMPORTANT This method is declared package-private to prevent regular
+	 * plug-ins from downcasting IWorkbench to Workbench and getting hold of the
+	 * workbench advisor that would allow them to tamper with the workbench. The
+	 * workbench advisor is internal to the application.
+	 * </p>
+	 */
+	/* package */
+	WorkbenchAdvisor getAdvisor() {
+		return advisor;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbench.
+	 */
+	public Display getDisplay() {
+		return display;
+	}
+
+	/**
+	 * Returns the default perspective id, which may be <code>null</code>.
+	 * 
+	 * @return the default perspective id, or <code>null</code>
+	 */
+	public String getDefaultPerspectiveId() {
+		return getAdvisor().getInitialWindowPerspectiveId();
+	}
+
+	/**
+	 * Returns the default workbench window page input.
+	 * 
+	 * @return the default window page input or <code>null</code> if none
+	 */
+	public IAdaptable getDefaultPageInput() {
+		return getAdvisor().getDefaultPageInput();
+	}
+
+	/**
+	 * Returns the id of the preference page that should be presented most
+	 * prominently.
+	 * 
+	 * @return the id of the preference page, or <code>null</code> if none
+	 */
+	public String getMainPreferencePageId() {
+		String id = getAdvisor().getMainPreferencePageId();
+		return id;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench
+	 * 
+	 * @since 3.0
+	 */
+	public IElementFactory getElementFactory(String factoryId) {
+		Assert.isNotNull(factoryId);
+		return WorkbenchPlugin.getDefault().getElementFactory(factoryId);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getProgressService()
+	 */
+	public IProgressService getProgressService() {
+		return (IProgressService) e4Context.get(IProgressService.class
+				.getName());
+	}
+
+	private WorkbenchActivitySupport workbenchActivitySupport;
+
+	private WorkbenchCommandSupport workbenchCommandSupport;
+
+	private WorkbenchContextSupport workbenchContextSupport;
+
+	/**
+	 * The single instance of the binding manager used by the workbench. This is
+	 * initialized in <code>Workbench.init(Display)</code> and then never
+	 * changed. This value will only be <code>null</code> if the initialization
+	 * call has not yet completed.
+	 * 
+	 * @since 3.1
+	 */
+	private BindingManager bindingManager;
+
+	/**
+	 * The single instance of the command manager used by the workbench. This is
+	 * initialized in <code>Workbench.init(Display)</code> and then never
+	 * changed. This value will only be <code>null</code> if the initialization
+	 * call has not yet completed.
+	 * 
+	 * @since 3.1
+	 */
+	private CommandManager commandManager;
+
+	/**
+	 * The single instance of the context manager used by the workbench. This is
+	 * initialized in <code>Workbench.init(Display)</code> and then never
+	 * changed. This value will only be <code>null</code> if the initialization
+	 * call has not yet completed.
+	 * 
+	 * @since 3.1
+	 */
+	private ContextManager contextManager;
+
+	public IWorkbenchActivitySupport getActivitySupport() {
+		return (IWorkbenchActivitySupport) e4Context
+				.get(IWorkbenchActivitySupport.class.getName());
+	}
+
+	public IWorkbenchCommandSupport getCommandSupport() {
+		return (IWorkbenchCommandSupport) e4Context
+				.get(IWorkbenchCommandSupport.class.getName());
+	}
+
+	public IWorkbenchContextSupport getContextSupport() {
+		return (IWorkbenchContextSupport) e4Context
+				.get(IWorkbenchContextSupport.class.getName());
+	}
+
+	/**
+	 * This method should not be called outside the framework.
+	 * 
+	 * @return The context manager.
+	 */
+	public ContextManager getContextManager() {
+		return (ContextManager) e4Context.get(ContextManager.class.getName());
+	}
+
+	private final IWindowListener windowListener = new IWindowListener() {
+
+		public void windowActivated(IWorkbenchWindow window) {
+			updateActiveWorkbenchWindowMenuManager(true);
+		}
+
+		public void windowClosed(IWorkbenchWindow window) {
+			updateActiveWorkbenchWindowMenuManager(true);
+		}
+
+		public void windowDeactivated(IWorkbenchWindow window) {
+			updateActiveWorkbenchWindowMenuManager(true);
+		}
+
+		public void windowOpened(IWorkbenchWindow window) {
+			updateActiveWorkbenchWindowMenuManager(true);
+		}
+	};
+
+	private final IBindingManagerListener bindingManagerListener = new IBindingManagerListener() {
+
+		public void bindingManagerChanged(
+				BindingManagerEvent bindingManagerEvent) {
+			if (bindingManagerEvent.isActiveBindingsChanged()) {
+				updateActiveWorkbenchWindowMenuManager(true);
+			}
+		}
+	};
+
+	/**
+	 * The source provider that tracks the activation of action sets within the
+	 * workbench. This source provider is <code>null</code> until
+	 * {@link #initializeDefaultServices()} is called.
+	 */
+	private ActionSetSourceProvider actionSetSourceProvider;
+
+	private WorkbenchWindow activeWorkbenchWindow = null;
+
+	private void updateActiveWorkbenchWindowMenuManager(boolean textOnly) {
+		if (activeWorkbenchWindow != null) {
+			activeWorkbenchWindow
+					.removeActionSetsListener(actionSetSourceProvider);
+			activeWorkbenchWindow = null;
+		}
+		boolean actionSetsUpdated = false;
+
+		final IWorkbenchWindow workbenchWindow = getActiveWorkbenchWindow();
+
+		if (workbenchWindow instanceof WorkbenchWindow) {
+			activeWorkbenchWindow = (WorkbenchWindow) workbenchWindow;
+			if (activeWorkbenchWindow.isClosing()) {
+				return;
+			}
+
+			// Update the action sets.
+			final Shell windowShell = activeWorkbenchWindow.getShell();
+			final Shell activeShell = getDisplay().getActiveShell();
+			final IContextService service = (IContextService) getService(IContextService.class);
+			if (Util.equals(windowShell, activeShell)
+					|| service.getShellType(activeShell) == IContextService.TYPE_WINDOW) {
+				activeWorkbenchWindow
+						.addActionSetsListener(actionSetSourceProvider);
+				final WorkbenchPage page = activeWorkbenchWindow
+						.getActiveWorkbenchPage();
+				final IActionSetDescriptor[] newActionSets;
+				if (page != null) {
+					newActionSets = page.getActionSets();
+					final ActionSetsEvent event = new ActionSetsEvent(
+							newActionSets);
+					actionSetSourceProvider.actionSetsChanged(event);
+					actionSetsUpdated = true;
+				}
+			}
+
+			final MenuManager menuManager = activeWorkbenchWindow
+					.getMenuManager();
+
+			if (textOnly) {
+				menuManager.update(IAction.TEXT);
+			} else {
+				menuManager.update(true);
+			}
+		}
+
+		if (!actionSetsUpdated) {
+			final ActionSetsEvent event = new ActionSetsEvent(null);
+			actionSetSourceProvider.actionSetsChanged(event);
+		}
+	}
+
+	private ActivityPersistanceHelper activityHelper;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getIntroManager()
+	 */
+	public IIntroManager getIntroManager() {
+		return getWorkbenchIntroManager();
+	}
+
+	/**
+	 * @return the workbench intro manager
+	 * @since 3.0
+	 */
+	/* package */WorkbenchIntroManager getWorkbenchIntroManager() {
+		return (WorkbenchIntroManager) e4Context
+				.get(WorkbenchIntroManager.class.getName());
+	}
+
+	private WorkbenchIntroManager introManager;
+
+	/**
+	 * @return the intro extension for this workbench.
+	 * 
+	 * @since 3.0
+	 */
+	public IntroDescriptor getIntroDescriptor() {
+		if (introDescriptor == null) {
+			IIntroRegistry introRegistry = (IIntroRegistry) e4Context
+					.get(IIntroRegistry.class.getName());
+			if (introRegistry != null && introRegistry.getIntroCount() > 0) {
+				// TODO Avoid referencing platform (bug 272502)
+				IProduct product = Platform.getProduct();
+				if (product != null) {
+					introDescriptor = (IntroDescriptor) introRegistry
+							.getIntroForProduct(product.getId());
+				}
+			}
+		}
+		return introDescriptor;
+	}
+
+	/**
+	 * This method exists as a test hook. This method should
+	 * <strong>NEVER</strong> be called by clients.
+	 * 
+	 * @param descriptor
+	 *            The intro descriptor to use.
+	 * @since 3.0
+	 */
+	public void setIntroDescriptor(IntroDescriptor descriptor) {
+		if (getIntroManager().getIntro() != null) {
+			getIntroManager().closeIntro(getIntroManager().getIntro());
+		}
+		introDescriptor = descriptor;
+	}
+
+	/**
+	 * The descriptor for the intro extension that is valid for this workspace,
+	 * <code>null</code> if none.
+	 */
+	private IntroDescriptor introDescriptor;
+
+	private IExtensionTracker tracker;
+
+	private IRegistryChangeListener startupRegistryListener = new IRegistryChangeListener() {
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(
+		 * org.eclipse.core.runtime.IRegistryChangeEvent)
+		 */
+		public void registryChanged(IRegistryChangeEvent event) {
+			final IExtensionDelta[] deltas = event.getExtensionDeltas(
+					PlatformUI.PLUGIN_ID,
+					IWorkbenchRegistryConstants.PL_STARTUP);
+			if (deltas.length == 0) {
+				return;
+			}
+			final String disabledPlugins = PrefUtil
+					.getInternalPreferenceStore()
+					.getString(
+							IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
+
+			for (int i = 0; i < deltas.length; i++) {
+				IExtension extension = deltas[i].getExtension();
+				if (deltas[i].getKind() == IExtensionDelta.REMOVED) {
+					continue;
+				}
+
+				// if the plugin is not in the set of disabled plugins,
+				// then
+				// execute the code to start it
+				if (disabledPlugins.indexOf(extension.getNamespace()) == -1) {
+					SafeRunner.run(new EarlyStartupRunnable(extension));
+				}
+			}
+
+		}
+	};
+
+	private String factoryID;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getThemeManager()
+	 */
+	public IThemeManager getThemeManager() {
+		return (IThemeManager) e4Context.get(IThemeManager.class.getName());
+	}
+
+	/**
+	 * Returns <code>true</code> if the workbench is running, <code>false</code>
+	 * if it has been terminated.
+	 * 
+	 * @return <code>true</code> if the workbench is running, <code>false</code>
+	 *         if it has been terminated.
+	 */
+	public boolean isRunning() {
+		return runEventLoop;
+	}
+
+	/**
+	 * Return the presentation ID specified by the preference or the default ID
+	 * if undefined.
+	 * 
+	 * @return the presentation ID
+	 * @see IWorkbenchPreferenceConstants#PRESENTATION_FACTORY_ID
+	 */
+	public String getPresentationId() {
+		if (factoryID != null) {
+			return factoryID;
+		}
+
+		factoryID = PrefUtil.getAPIPreferenceStore().getString(
+				IWorkbenchPreferenceConstants.PRESENTATION_FACTORY_ID);
+
+		// Workaround for bug 58975 - New preference mechanism does not properly
+		// initialize defaults
+		// Ensure that the UI plugin has started too.
+		if (factoryID == null || factoryID.equals("")) { //$NON-NLS-1$
+			factoryID = IWorkbenchConstants.DEFAULT_PRESENTATION_ID;
+		}
+		return factoryID;
+	}
+
+	/**
+	 * <p>
+	 * Indicates the start of a large update within the workbench. This is used
+	 * to disable CPU-intensive, change-sensitive services that were temporarily
+	 * disabled in the midst of large changes. This method should always be
+	 * called in tandem with <code>largeUpdateEnd</code>, and the event loop
+	 * should not be allowed to spin before that method is called.
+	 * </p>
+	 * <p>
+	 * Important: always use with <code>largeUpdateEnd</code>!
+	 * </p>
+	 */
+	public final void largeUpdateStart() {
+		if (largeUpdates++ == 0) {
+			// TODO Consider whether these lines still need to be here.
+			// workbenchCommandSupport.setProcessing(false);
+			// workbenchContextSupport.setProcessing(false);
+
+			final IWorkbenchWindow[] windows = getWorkbenchWindows();
+			for (int i = 0; i < windows.length; i++) {
+				IWorkbenchWindow window = windows[i];
+				if (window instanceof WorkbenchWindow) {
+					((WorkbenchWindow) window).largeUpdateStart();
+				}
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Indicates the end of a large update within the workbench. This is used to
+	 * re-enable services that were temporarily disabled in the midst of large
+	 * changes. This method should always be called in tandem with
+	 * <code>largeUpdateStart</code>, and the event loop should not be allowed
+	 * to spin before this method is called.
+	 * </p>
+	 * <p>
+	 * Important: always protect this call by using <code>finally</code>!
+	 * </p>
+	 */
+	public final void largeUpdateEnd() {
+		if (--largeUpdates == 0) {
+			// TODO Consider whether these lines still need to be here.
+			// workbenchCommandSupport.setProcessing(true);
+			// workbenchContextSupport.setProcessing(true);
+
+			// Perform window-specific blocking.
+			final IWorkbenchWindow[] windows = getWorkbenchWindows();
+			for (int i = 0; i < windows.length; i++) {
+				IWorkbenchWindow window = windows[i];
+				if (window instanceof WorkbenchWindow) {
+					((WorkbenchWindow) window).largeUpdateEnd();
+				}
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getExtensionTracker()
+	 */
+	public IExtensionTracker getExtensionTracker() {
+		return (IExtensionTracker) e4Context.get(IExtensionTracker.class
+				.getName());
+	}
+
+	/**
+	 * Adds the listener that handles startup plugins
+	 * 
+	 * @since 3.1
+	 */
+	private void addStartupRegistryListener() {
+		IExtensionRegistry registry = Platform.getExtensionRegistry();
+		registry.addRegistryChangeListener(startupRegistryListener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getHelpSystem()
+	 */
+	public IWorkbenchHelpSystem getHelpSystem() {
+		return (IWorkbenchHelpSystem) e4Context.get(IWorkbenchHelpSystem.class
+				.getName());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getHelpSystem()
+	 */
+	public IWorkbenchBrowserSupport getBrowserSupport() {
+		return (IWorkbenchBrowserSupport) e4Context
+				.get(IWorkbenchBrowserSupport.class.getName());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getViewRegistry()
+	 */
+	public IViewRegistry getViewRegistry() {
+		return WorkbenchPlugin.getDefault().getViewRegistry();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getNewWizardRegistry()
+	 */
+	public IWizardRegistry getNewWizardRegistry() {
+		return WorkbenchPlugin.getDefault().getNewWizardRegistry();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getImportWizardRegistry()
+	 */
+	public IWizardRegistry getImportWizardRegistry() {
+		return WorkbenchPlugin.getDefault().getImportWizardRegistry();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbench#getExportWizardRegistry()
+	 */
+	public IWizardRegistry getExportWizardRegistry() {
+		return WorkbenchPlugin.getDefault().getExportWizardRegistry();
+	}
+
+	public final Object getAdapter(final Class key) {
+		return serviceLocator.getService(key);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.services.IServiceLocator#getService(java.lang.Object)
+	 */
+	public final Object getService(final Class key) {
+		return serviceLocator.getService(key);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.services.IServiceLocator#hasService(java.lang.Object)
+	 */
+	public final boolean hasService(final Class key) {
+		return serviceLocator.hasService(key);
+	}
+
+	/**
+	 * Registers a service with this locator. If there is an existing service
+	 * matching the same <code>api</code> and it implements {@link IDisposable},
+	 * it will be disposed.
+	 * 
+	 * @param api
+	 *            This is the interface that the service implements. Must not be
+	 *            <code>null</code>.
+	 * @param service
+	 *            The service to register. This must be some implementation of
+	 *            <code>api</code>. This value must not be <code>null</code>.
+	 */
+	public final void registerService(final Class api, final Object service) {
+		serviceLocator.registerService(api, service);
+	}
+
+	/**
+	 * The source provider that tracks which context menus (i.e., menus with
+	 * target identifiers) are now showing. This value is <code>null</code>
+	 * until {@link #initializeDefaultServices()} is called.
+	 */
+	private MenuSourceProvider menuSourceProvider;
+
+	private IEclipseContext e4Context;
+
+	private org.eclipse.e4.workbench.ui.internal.Workbench e4Workbench;
+
+	/**
+	 * Adds the ids of a menu that is now showing to the menu source provider.
+	 * This is used for legacy action-based handlers which need to become active
+	 * only for the duration of a menu being visible.
+	 * 
+	 * @param menuIds
+	 *            The identifiers of the menu that is now showing; must not be
+	 *            <code>null</code>.
+	 * @param localSelection
+	 * @param localEditorInput
+	 */
+	public final void addShowingMenus(final Set menuIds,
+			final ISelection localSelection, final ISelection localEditorInput) {
+		menuSourceProvider.addShowingMenus(menuIds, localSelection,
+				localEditorInput);
+		e4Context.set(ISources.ACTIVE_MENU_NAME, menuIds);
+		e4Context.set(ISources.ACTIVE_MENU_SELECTION_NAME, localSelection);
+		e4Context.set(ISources.ACTIVE_MENU_EDITOR_INPUT_NAME, localEditorInput);
+		org.eclipse.e4.workbench.ui.internal.Activator.trace(
+				org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_MENUS,
+				"Adding menus " + menuIds + ", selection: " + localSelection, //$NON-NLS-1$ //$NON-NLS-2$
+				null);
+	}
+
+	/**
+	 * Removes the ids of a menu that is now hidden from the menu source
+	 * provider. This is used for legacy action-based handlers which need to
+	 * become active only for the duration of a menu being visible.
+	 * 
+	 * @param menuIds
+	 *            The identifiers of the menu that is now hidden; must not be
+	 *            <code>null</code>.
+	 * @param localSelection
+	 * @param localEditorInput
+	 */
+	public final void removeShowingMenus(final Set menuIds,
+			final ISelection localSelection, final ISelection localEditorInput) {
+		menuSourceProvider.removeShowingMenus(menuIds, localSelection,
+				localEditorInput);
+		e4Context.set(ISources.ACTIVE_MENU_NAME, null);
+		e4Context.set(ISources.ACTIVE_MENU_SELECTION_NAME, null);
+		e4Context.set(ISources.ACTIVE_MENU_EDITOR_INPUT_NAME, null);
+		org.eclipse.e4.workbench.ui.internal.Activator.trace(
+				org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_MENUS,
+				"Clearing menus " + menuIds, null); //$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbench#saveAll(org.eclipse.jface.window.IShellProvider
+	 * , org.eclipse.jface.operation.IRunnableContext,
+	 * org.eclipse.ui.ISaveableFilter, boolean)
+	 */
+	public boolean saveAll(IShellProvider shellProvider,
+			IRunnableContext runnableContext, ISaveableFilter filter,
+			boolean confirm) {
+		SaveablesList saveablesList = (SaveablesList) PlatformUI.getWorkbench()
+				.getService(ISaveablesLifecycleListener.class);
+		Saveable[] saveables = saveablesList.getOpenModels();
+		List toSave = getFilteredSaveables(filter, saveables);
+		if (toSave.isEmpty())
+			return true;
+
+		if (!confirm) {
+			return !saveablesList.saveModels(toSave, shellProvider,
+					runnableContext);
+		}
+
+		// We must negate the result since false is cancel saveAll
+		return !saveablesList.promptForSaving(toSave, shellProvider,
+				runnableContext, true, false);
+	}
+
+	/*
+	 * Apply the given filter to the list of saveables
+	 */
+	private List getFilteredSaveables(ISaveableFilter filter,
+			Saveable[] saveables) {
+		List toSave = new ArrayList();
+		if (filter == null) {
+			for (int i = 0; i < saveables.length; i++) {
+				Saveable saveable = saveables[i];
+				if (saveable.isDirty())
+					toSave.add(saveable);
+			}
+		} else {
+			SaveablesList saveablesList = (SaveablesList) getService(ISaveablesLifecycleListener.class);
+			for (int i = 0; i < saveables.length; i++) {
+				Saveable saveable = saveables[i];
+				if (saveable.isDirty()) {
+					IWorkbenchPart[] parts = saveablesList
+							.getPartsForSaveable(saveable);
+					if (matchesFilter(filter, saveable, parts))
+						toSave.add(saveable);
+				}
+			}
+		}
+		return toSave;
+	}
+
+	/*
+	 * Test whether the given filter matches the saveable
+	 */
+	private boolean matchesFilter(ISaveableFilter filter, Saveable saveable,
+			IWorkbenchPart[] parts) {
+		return filter == null || filter.select(saveable, parts);
+	}
+
+	public ServiceLocator getServiceLocator() {
+		return serviceLocator;
+	}
+
+	// TBD this seems like an API that should be in the model
+	public void addCommand(String id, String name) {
+		MApplication app = (MApplication) e4Context.get(MApplication.class
+				.getName());
+		MCommand newCommand = MApplicationFactory.eINSTANCE.createCommand();
+		newCommand.setId(id);
+		newCommand.setCommandName(name);
+		app.getCommands().add(newCommand);
+
+		ECommandService cs = (ECommandService) e4Context
+				.get(ECommandService.class.getName());
+		Command command = cs.getCommand(id);
+		if (!command.isDefined()) {
+			Category category = cs
+					.getCategory(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+			if (!category.isDefined())
+				category.define("Action Sets", null); //$NON-NLS-1$
+			command.define(newCommand.getCommandName(), null, category);
+		}
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPage.java
new file mode 100644
index 0000000..1c049ec
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPage.java
@@ -0,0 +1,3562 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
+import org.eclipse.e4.compatibility.LegacyEditor;
+import org.eclipse.e4.compatibility.LegacyView;
+import org.eclipse.e4.core.services.IDisposable;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ModelEditorReference;
+import org.eclipse.e4.extensions.ModelReference;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MContribution;
+import org.eclipse.e4.ui.model.application.MESCElement;
+import org.eclipse.e4.ui.model.application.MEditor;
+import org.eclipse.e4.ui.model.application.MEditorSashContainer;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MPerspectiveStack;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
+import org.eclipse.e4.workbench.ui.internal.IValueFunction;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.INavigationHistory;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IReusableEditor;
+import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.MultiPartInitException;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+import org.eclipse.ui.internal.misc.UIStats;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.EditorDescriptor;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
+import org.eclipse.ui.internal.registry.UIExtensionTracker;
+import org.eclipse.ui.internal.tweaklets.GrabFocus;
+import org.eclipse.ui.internal.tweaklets.TabBehaviour;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.tweaklets.WorkbenchImplementation;
+import org.eclipse.ui.internal.util.PrefUtil;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.part.AbstractMultiEditor;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.presentations.IStackPresentationSite;
+
+/**
+ * A collection of views and editors in a workbench.
+ */
+public class WorkbenchPage extends CompatibleWorkbenchPage implements
+		IWorkbenchPage {
+
+	private static final String ATT_AGGREGATE_WORKING_SET_ID = "aggregateWorkingSetId"; //$NON-NLS-1$
+
+	private static final IEditorReference[] noEditorRefs = new IEditorReference[0];
+
+	protected WorkbenchWindow window;
+
+	private IAdaptable input;
+
+	private IWorkingSet workingSet;
+
+	private AggregateWorkingSet aggregateWorkingSet;
+
+	private Composite composite;
+
+	private EditorManager editorMgr;
+
+	private ArrayList removedEditors = new ArrayList();
+
+	private ListenerList propertyChangeListeners = new ListenerList();
+
+	private WorkbenchPagePartList partList = null;
+
+	private IActionBars actionBars;
+
+	private ActionSetManager actionSets;
+
+	private ViewFactory viewFactory;
+
+	private PerspectiveList perspList = new PerspectiveList();
+
+	private PerspectiveDescriptor deferredActivePersp;
+
+	private NavigationHistory navigationHistory = null;
+
+	private IStickyViewManager stickyViewMan = StickyViewManager
+			.getInstance(this);
+
+	/**
+	 * If we're in the process of activating a part, this points to the new
+	 * part. Otherwise, this is null.
+	 */
+	private IWorkbenchPartReference partBeingActivated = null;
+
+	/**
+	 * If a part is being opened, don't allow a forceFocus() to request its
+	 * activation as well.
+	 * 
+	 * @since 3.4
+	 */
+	private boolean partBeingOpened = false;
+
+	/**
+	 * Contains a list of perspectives that may be dirty due to plugin
+	 * installation and removal.
+	 */
+	private Set dirtyPerspectives = new HashSet();
+
+	private IPropertyChangeListener workingSetPropertyChangeListener = new IPropertyChangeListener() {
+		/*
+		 * Remove the working set from the page if the working set is deleted.
+		 */
+		public void propertyChange(PropertyChangeEvent event) {
+			String property = event.getProperty();
+			if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)) {
+				if (event.getOldValue().equals(workingSet)) {
+					setWorkingSet(null);
+				}
+
+				// room for optimization here
+				List newList = new ArrayList(Arrays.asList(workingSets));
+				if (newList.remove(event.getOldValue())) {
+					setWorkingSets((IWorkingSet[]) newList
+							.toArray(new IWorkingSet[newList.size()]));
+				}
+			}
+		}
+	};
+
+	private IExtensionTracker tracker;
+
+	private IWorkingSet[] workingSets = new IWorkingSet[0];
+	private String aggregateWorkingSetId;
+
+	private MWindow e4Window;
+
+	private IEclipseContext e4Context;
+
+	private ISelectionService selectionService;
+
+	/**
+	 * Constructs a new page with a given perspective and input.
+	 * 
+	 * @param w
+	 *            the parent window
+	 * @param layoutID
+	 *            must not be <code>null</code>
+	 * @param input
+	 *            the page input
+	 * @throws WorkbenchException
+	 *             on null layout id
+	 */
+	public WorkbenchPage(WorkbenchWindow w, String layoutID, IAdaptable input)
+			throws WorkbenchException {
+		super();
+		if (layoutID == null) {
+			throw new WorkbenchException(
+					WorkbenchMessages.WorkbenchPage_UndefinedPerspective);
+		}
+		init(w, layoutID, input, true);
+	}
+
+	/**
+	 * Constructs a page. <code>restoreState(IMemento)</code> should be called
+	 * to restore this page from data stored in a persistance file.
+	 * 
+	 * @param w
+	 *            the parent window
+	 * @param input
+	 *            the page input
+	 * @throws WorkbenchException
+	 */
+	public WorkbenchPage(WorkbenchWindow w, IAdaptable input)
+			throws WorkbenchException {
+		super();
+		init(w, null, input, false);
+	}
+
+	/**
+	 * Activates a part. The part will be brought to the front and given focus.
+	 * 
+	 * @param part
+	 *            the part to activate
+	 */
+	public void activate(IWorkbenchPart part) {
+		// Sanity check.
+		if (part == null || !certifyPart(part) || window.isClosing()) {
+			return;
+		}
+
+		// Activate the part and set its focus
+		IWorkbenchPartReference ref = getReference(part);
+		if (ref instanceof ModelReference) {
+			ModelReference modelRef = (ModelReference) ref;
+			MPart modelElement = modelRef.getModel();
+			if (modelElement != null) {
+				AbstractPartRenderer renderer = (AbstractPartRenderer) modelElement
+						.getFactory();
+				if (renderer != null)
+					renderer.activate(modelElement);
+
+			}
+		}
+
+	}
+
+	/**
+	 * Add a fast view.
+	 */
+	public void addFastView(IViewReference ref) {
+	}
+
+	/**
+	 * Add a fast view.
+	 */
+	public void makeFastView(IViewReference ref) {
+	}
+
+	/**
+	 * Adds an IPartListener to the part service.
+	 */
+	public void addPartListener(IPartListener l) {
+		partList.getPartService().addPartListener(l);
+	}
+
+	/**
+	 * Adds an IPartListener to the part service.
+	 */
+	public void addPartListener(IPartListener2 l) {
+		partList.getPartService().addPartListener(l);
+	}
+
+	/**
+	 * Implements IWorkbenchPage
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#addPropertyChangeListener(IPropertyChangeListener)
+	 * @since 2.0
+	 * @deprecated individual views should store a working set if needed and
+	 *             register a property change listener directly with the working
+	 *             set manager to receive notification when the view working set
+	 *             is removed.
+	 */
+	public void addPropertyChangeListener(IPropertyChangeListener listener) {
+		propertyChangeListeners.add(listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void addSelectionListener(ISelectionListener listener) {
+		selectionService.addSelectionListener(listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void addSelectionListener(String partId, ISelectionListener listener) {
+		selectionService.addSelectionListener(partId, listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void addPostSelectionListener(ISelectionListener listener) {
+		selectionService.addPostSelectionListener(listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void addPostSelectionListener(String partId,
+			ISelectionListener listener) {
+		selectionService.addPostSelectionListener(partId, listener);
+	}
+
+	/**
+	 * Moves a part forward in the Z order of a perspective so it is visible. If
+	 * the part is in the same stack as the active part, the new part is
+	 * activated.
+	 * 
+	 * @param part
+	 *            the part to bring to move forward
+	 */
+	public void bringToTop(IWorkbenchPart part) {
+		// Sanity check.
+		Perspective persp = getActivePerspective();
+		if (persp == null || !certifyPart(part)) {
+			return;
+		}
+
+		if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
+			return;
+		}
+
+		// TBD we have no shared parts so far. Processing below should be
+		// updated once shared parts are implemented
+		if (part instanceof EditorPart) {
+			MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
+					.internalGetEditorArea());
+			String editorID = ((EditorPart) part).getEditorSite().getId();
+			IEditorInput editorInput = ((EditorPart) part).getEditorInput();
+			MEditor editorPart = findEditor(ea, editorID, editorInput);
+			if (editorPart != null) {
+				editorPart.setVisible(true);
+				ea.setActiveChild((MESCElement) editorPart);
+			} else {
+				try {
+					openEditor(editorInput, editorID, true, MATCH_NONE);
+				} catch (PartInitException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		} else {
+			// TBD implement functionality for views
+		}
+	}
+
+	/**
+	 * Shows a view.
+	 * 
+	 * Assumes that a busy cursor is active.
+	 */
+	protected IViewPart busyShowView(String viewID, String secondaryID, int mode)
+			throws PartInitException {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return null;
+		}
+
+		// If this view is already visible just return.
+		IViewReference ref = persp.findView(viewID, secondaryID);
+		IViewPart view = null;
+		if (ref != null) {
+			view = ref.getView(true);
+		}
+		if (view != null) {
+			busyShowView(view, mode);
+			return view;
+		}
+
+		// Show the view.
+		view = persp.showView(viewID, secondaryID);
+		if (view != null) {
+
+			window.firePerspectiveChanged(this, getPerspective(), null,
+					CHANGE_VIEW_SHOW);
+			window.firePerspectiveChanged(this, getPerspective(),
+					CHANGE_VIEW_SHOW);
+		}
+		return view;
+	}
+
+	/*
+	 * Performs showing of the view in the given mode.
+	 */
+	private void busyShowView(IViewPart part, int mode) {
+		if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
+			return;
+		}
+	}
+
+	/**
+	 * Returns whether a part exists in the current page.
+	 */
+	private boolean certifyPart(IWorkbenchPart part) {
+		// Workaround for bug 22325
+		if (part != null && !(part.getSite() instanceof PartSite)) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Closes the perspective.
+	 */
+	public boolean close() {
+		final boolean[] ret = new boolean[1];
+		BusyIndicator.showWhile(null, new Runnable() {
+			public void run() {
+				ret[0] = window.closePage(WorkbenchPage.this, true);
+			}
+		});
+		return ret[0];
+	}
+
+	/**
+	 * See IWorkbenchPage
+	 */
+	public boolean closeAllSavedEditors() {
+		// get the Saved editors
+		IEditorReference editors[] = getEditorReferences();
+		IEditorReference savedEditors[] = new IEditorReference[editors.length];
+		int j = 0;
+		for (int i = 0; i < editors.length; i++) {
+			IEditorReference editor = editors[i];
+			if (!editor.isDirty()) {
+				savedEditors[j++] = editor;
+			}
+		}
+		// there are no unsaved editors
+		if (j == 0) {
+			return true;
+		}
+		IEditorReference[] newSaved = new IEditorReference[j];
+		System.arraycopy(savedEditors, 0, newSaved, 0, j);
+		return closeEditors(newSaved, false);
+	}
+
+	/**
+	 * See IWorkbenchPage
+	 */
+	public boolean closeAllEditors(boolean save) {
+		return closeEditors(getEditorReferences(), save);
+	}
+
+	/**
+	 * See IWorkbenchPage
+	 */
+	public boolean closeEditors(IEditorReference[] refArray, boolean save) {
+		if (refArray.length == 0) {
+			return true;
+		}
+
+		// Check if we're being asked to close any parts that are already closed
+		// or cannot
+		// be closed at this time
+		ArrayList toClose = new ArrayList();
+		for (int i = 0; i < refArray.length; i++) {
+			IEditorReference reference = refArray[i];
+
+			// If we're in the middle of creating this part, this is a
+			// programming error. Abort the entire
+			// close operation. This usually occurs if someone tries to open a
+			// dialog in a method that
+			// isn't allowed to do so, and a *syncExec tries to close the part.
+			// If this shows up in a log
+			// file with a dialog's event loop on the stack, then the code that
+			// opened the dialog is usually
+			// at fault.
+			if (reference == partBeingActivated) {
+				WorkbenchPlugin
+						.log(new RuntimeException(
+								"WARNING: Blocked recursive attempt to close part " //$NON-NLS-1$
+										+ partBeingActivated.getId()
+										+ " while still in the middle of activating it")); //$NON-NLS-1$
+				return false;
+			}
+
+			if (reference instanceof WorkbenchPartReference) {
+				WorkbenchPartReference ref = (WorkbenchPartReference) reference;
+
+				// If we're being asked to close a part that is disposed (ie:
+				// already closed),
+				// skip it and proceed with closing the remaining parts.
+				if (ref.isDisposed()) {
+					continue;
+				}
+			}
+
+			toClose.add(reference);
+		}
+
+		IEditorReference[] editorRefs = (IEditorReference[]) toClose
+				.toArray(new IEditorReference[toClose.size()]);
+
+		// if active navigation position belongs to an editor being closed,
+		// update it
+		// (The navigation position for an editor N was updated as an editor N +
+		// 1
+		// was activated. As a result, all but the last editor have up-to-date
+		// navigation positions.)
+		for (int i = 0; i < editorRefs.length; i++) {
+			IEditorReference ref = editorRefs[i];
+			if (ref == null)
+				continue;
+			IEditorPart oldPart = ref.getEditor(false);
+			if (oldPart == null)
+				continue;
+			if (navigationHistory.updateActive(oldPart))
+				break; // updated - skip the rest
+		}
+
+		// notify the model manager before the close
+		List partsToClose = new ArrayList();
+		for (int i = 0; i < editorRefs.length; i++) {
+			IEditorPart refPart = editorRefs[i].getEditor(false);
+			if (refPart != null) {
+				partsToClose.add(refPart);
+			}
+		}
+		SaveablesList modelManager = null;
+		Object postCloseInfo = null;
+		if (partsToClose.size() > 0) {
+			modelManager = (SaveablesList) getWorkbenchWindow().getService(
+					ISaveablesLifecycleListener.class);
+			// this may prompt for saving and return null if the user canceled:
+			postCloseInfo = modelManager.preCloseParts(partsToClose, save,
+					getWorkbenchWindow());
+			if (postCloseInfo == null) {
+				return false;
+			}
+		}
+
+		// Fire pre-removal changes
+		for (int i = 0; i < editorRefs.length; i++) {
+			IEditorReference ref = editorRefs[i];
+
+			// Notify interested listeners before the close
+			window.firePerspectiveChanged(this, getPerspective(), ref,
+					CHANGE_EDITOR_CLOSE);
+
+		}
+
+		if (modelManager != null) {
+			modelManager.postClose(postCloseInfo);
+		}
+
+		// Close all editors.
+		for (int i = 0; i < editorRefs.length; i++) {
+			IEditorReference ref = editorRefs[i];
+
+			// Remove editor from the presentation
+
+			partRemoved(ref);
+			// now that it has disappeared from the model, dispose its context
+			MPart mEditorPart = ((ModelEditorReference) ref).getModel();
+			((IDisposable) mEditorPart.getContext()).dispose();
+			mEditorPart.setContext(null);
+		}
+
+		// Notify interested listeners after the close
+		window.firePerspectiveChanged(this, getPerspective(),
+				CHANGE_EDITOR_CLOSE);
+
+		// Return true on success.
+		return true;
+	}
+
+	/**
+	 * See IWorkbenchPage#closeEditor
+	 */
+	public boolean closeEditor(IEditorReference editorRef, boolean save) {
+		return closeEditors(new IEditorReference[] { editorRef }, save);
+	}
+
+	/**
+	 * See IWorkbenchPage#closeEditor
+	 */
+	public boolean closeEditor(IEditorPart editor, boolean save) {
+		IWorkbenchPartReference ref = getReference(editor);
+		if (ref instanceof IEditorReference) {
+			return closeEditors(
+					new IEditorReference[] { (IEditorReference) ref }, save);
+		}
+		return false;
+	}
+
+	/**
+	 * @see IWorkbenchPage#closePerspective(IPerspectiveDescriptor, boolean,
+	 *      boolean)
+	 */
+	public void closePerspective(IPerspectiveDescriptor desc,
+			boolean saveParts, boolean closePage) {
+		Perspective persp = findPerspective(desc);
+		if (persp != null) {
+			perspList.openedList.remove(persp);
+			perspList.usedList.remove(persp);
+
+			// If we close the last perspective there is no active one...
+			if (perspList.openedList.isEmpty())
+				perspList.setActive(null);
+		}
+	}
+
+	/**
+	 * Closes the specified perspective in this page. If this is not the last
+	 * perspective in the page, and it is active, then the perspective specified
+	 * by <code>descToActivate</code> will be activated. If the last perspective
+	 * in this page is closed, then all editors are closed. Views that are not
+	 * shown in other perspectives are closed as well. If <code>saveParts</code>
+	 * is <code>true</code>, the user will be prompted to save any unsaved
+	 * changes for parts that are being closed. The page itself is closed if
+	 * <code>closePage</code> is <code>true</code>.
+	 * 
+	 * @param desc
+	 *            the descriptor of the perspective to be closed
+	 * @param descToActivate
+	 *            the descriptor of the perspective to activate
+	 * @param saveParts
+	 *            whether the page's parts should be saved if closed
+	 * @param closePage
+	 *            whether the page itself should be closed if last perspective
+	 * @since 3.4
+	 */
+	public void closePerspective(IPerspectiveDescriptor desc,
+			IPerspectiveDescriptor descToActivate, boolean saveParts,
+			boolean closePage) {
+		Perspective persp = findPerspective(desc);
+		if (persp != null) {
+			perspList.openedList.remove(persp);
+			perspList.usedList.remove(persp);
+
+			// If we close the last perspective there is no active one...
+			if (perspList.openedList.isEmpty())
+				perspList.setActive(null);
+		}
+	}
+
+	/**
+	 * Closes the specified perspective. If last perspective, then entire page
+	 * is closed.
+	 * 
+	 * @param persp
+	 *            the perspective to be closed
+	 * @param saveParts
+	 *            whether the parts that are being closed should be saved
+	 *            (editors if last perspective, views if not shown in other
+	 *            parspectives)
+	 */
+	/* package */
+	void closePerspective(Perspective persp, boolean saveParts,
+			boolean closePage) {
+		closePerspective(persp, null, saveParts, closePage);
+	}
+
+	/**
+	 * Closes the specified perspective. If last perspective, then entire page
+	 * is closed.
+	 * 
+	 * @param persp
+	 *            the perspective to be closed
+	 * @param perspToActivate
+	 *            the perspective to activate
+	 * @param saveParts
+	 *            whether the parts that are being closed should be saved
+	 *            (editors if last perspective, views if not shown in other
+	 *            parspectives)
+	 */
+	/* package */
+	void closePerspective(Perspective persp, Perspective perspToActivate,
+			boolean saveParts, boolean closePage) {
+
+	}
+
+	/**
+	 * Forces all perspectives on the page to zoom out.
+	 */
+	public void unzoomAllPerspectives() {
+	}
+
+	/**
+	 * @see IWorkbenchPage#closeAllPerspectives(boolean, boolean)
+	 */
+	public void closeAllPerspectives(boolean saveEditors, boolean closePage) {
+
+		if (perspList.isEmpty()) {
+			return;
+		}
+
+		// Always unzoom
+		if (isZoomed()) {
+			zoomOut();
+		}
+
+		if (saveEditors) {
+			if (!saveAllEditors(true)) {
+				return;
+			}
+		}
+		// Close all editors
+		if (!closeAllEditors(false)) {
+			return;
+		}
+
+		// Deactivate the active perspective and part
+		setPerspective((Perspective) null);
+
+		// Close each perspective in turn
+		PerspectiveList oldList = perspList;
+		perspList = new PerspectiveList();
+		Iterator itr = oldList.iterator();
+		while (itr.hasNext()) {
+			closePerspective((Perspective) itr.next(), false, false);
+		}
+		if (closePage) {
+			close();
+		}
+	}
+
+	/**
+	 * Creates a new view set. Return null on failure.
+	 * 
+	 * @param desc
+	 *            the perspective descriptor
+	 * @param notify
+	 *            whether to fire a perspective opened event
+	 */
+	private Perspective createPerspective(PerspectiveDescriptor desc,
+			boolean notify) {
+		String label = desc.getId(); // debugging only
+		try {
+			UIStats.start(UIStats.CREATE_PERSPECTIVE, label);
+			Perspective persp = ((WorkbenchImplementation) Tweaklets
+					.get(WorkbenchImplementation.KEY)).createPerspective(desc,
+					this);
+			perspList.add(persp);
+			if (notify) {
+				window.firePerspectiveOpened(this, desc);
+			}
+			// if the perspective is fresh and uncustomzied then it is not dirty
+			// no reset will be prompted for
+			if (!desc.hasCustomDefinition()) {
+				dirtyPerspectives.remove(desc.getId());
+			}
+			return persp;
+		} catch (WorkbenchException e) {
+			if (!((Workbench) window.getWorkbench()).isStarting()) {
+				MessageDialog
+						.openError(
+								window.getShell(),
+								WorkbenchMessages.Error,
+								NLS
+										.bind(
+												WorkbenchMessages.Workbench_showPerspectiveError,
+												desc.getId()));
+			}
+			return null;
+		} finally {
+			UIStats.end(UIStats.CREATE_PERSPECTIVE, desc.getId(), label);
+		}
+	}
+
+	/**
+	 * This is called by child objects after a part has been added to the page.
+	 * The page will in turn notify its listeners.
+	 */
+	/* package */void partAdded(WorkbenchPartReference ref) {
+		partList.addPart(ref);
+	}
+
+	/**
+	 * This is called by child objects after a part has been added to the page.
+	 * The part will be queued for disposal after all listeners have been
+	 * notified
+	 */
+	/* package */void partRemoved(IWorkbenchPartReference ref) {
+		disposePart(ref);
+	}
+
+	private void disposePart(IWorkbenchPartReference ref) {
+		if (ref instanceof WorkbenchPartReference) {
+			partList.removePart((WorkbenchPartReference) ref);
+			((WorkbenchPartReference) ref).dispose();
+		} else if (ref instanceof ModelReference) {
+			MPart modelPart = ((ModelReference) ref).getModel();
+			partList.firePartClosed(ref);
+			modelPart.setVisible(false);
+		}
+	}
+
+	/**
+	 * Detaches a view from the WorkbenchWindow.
+	 */
+	public void detachView(IViewReference ref) {
+
+	}
+
+	/**
+	 * Removes a detachedwindow.
+	 */
+	public void attachView(IViewReference ref) {
+	}
+
+	/**
+	 * Cleanup.
+	 */
+	public void dispose() {
+
+		// Always unzoom
+		if (isZoomed()) {
+			zoomOut();
+		}
+
+	}
+
+	/**
+	 * @return NavigationHistory
+	 */
+	public INavigationHistory getNavigationHistory() {
+		return (INavigationHistory) e4Context.get(INavigationHistory.class
+				.getName());
+	}
+
+	/**
+	 * Edits the action sets.
+	 */
+	public boolean editActionSets() {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return false;
+		}
+
+		// Create list dialog.
+		CustomizePerspectiveDialog dlg = window
+				.createCustomizePerspectiveDialog(persp);
+
+		// Open.
+		boolean ret = (dlg.open() == Window.OK);
+		if (ret) {
+			window.updateActionSets();
+			window.firePerspectiveChanged(this, getPerspective(), CHANGE_RESET);
+			window.firePerspectiveChanged(this, getPerspective(),
+					CHANGE_RESET_COMPLETE);
+		}
+		return ret;
+	}
+
+	/**
+	 * Returns the first view manager with given ID.
+	 */
+	public Perspective findPerspective(IPerspectiveDescriptor desc) {
+		Iterator itr = perspList.iterator();
+		while (itr.hasNext()) {
+			Perspective mgr = (Perspective) itr.next();
+			if (desc.getId().equals(mgr.getDesc().getId())) {
+				return mgr;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * See IWorkbenchPage@findView.
+	 */
+	public IViewPart findView(String id) {
+		IViewReference ref = findViewReference(id);
+		if (ref == null) {
+			return null;
+		}
+		return ref.getView(true);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage
+	 */
+	public IViewReference findViewReference(String viewId) {
+		return findViewReference(viewId, null);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage
+	 */
+	public IViewReference findViewReference(String viewId, String secondaryId) {
+		MPart modelPart = ModeledPageLayout.findPart(e4Window, viewId);
+		if (modelPart instanceof MPart) {
+			Object obj = ((MPart) modelPart).getObject();
+			if (!(obj instanceof LegacyView))
+				return null;
+
+			LegacyView lv = (LegacyView) obj;
+			return (IViewReference) getReference(lv.getViewPart());
+		}
+		return null;
+	}
+
+	/**
+	 * Notify property change listeners about a property change.
+	 * 
+	 * @param changeId
+	 *            the change id
+	 * @param oldValue
+	 *            old property value
+	 * @param newValue
+	 *            new property value
+	 */
+	private void firePropertyChange(String changeId, Object oldValue,
+			Object newValue) {
+
+		UIListenerLogging.logPagePropertyChanged(this, changeId, oldValue,
+				newValue);
+
+		Object[] listeners = propertyChangeListeners.getListeners();
+		PropertyChangeEvent event = new PropertyChangeEvent(this, changeId,
+				oldValue, newValue);
+
+		for (int i = 0; i < listeners.length; i++) {
+			((IPropertyChangeListener) listeners[i]).propertyChange(event);
+		}
+	}
+
+	/*
+	 * Returns the action bars.
+	 */
+	public IActionBars getActionBars() {
+		if (actionBars == null) {
+			actionBars = new WWinActionBars(window);
+		}
+		return actionBars;
+	}
+
+	/**
+	 * Returns an array of the visible action sets.
+	 */
+	public IActionSetDescriptor[] getActionSets() {
+
+		Collection visibleItems = actionSets.getVisibleItems();
+		return (IActionSetDescriptor[]) visibleItems
+				.toArray(new IActionSetDescriptor[visibleItems.size()]);
+	}
+
+	/**
+	 * @see IWorkbenchPage
+	 */
+	public IEditorPart getActiveEditor() {
+		return partList.getActiveEditor();
+	}
+
+	/**
+	 * Returns the reference for the active editor, or <code>null</code> if
+	 * there is no active editor.
+	 * 
+	 * @return the active editor reference or <code>null</code>
+	 */
+	public IEditorReference getActiveEditorReference() {
+		return partList.getActiveEditorReference();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPartService
+	 */
+	public IWorkbenchPart getActivePart() {
+		return partList.getActivePart();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPartService
+	 */
+	public IWorkbenchPartReference getActivePartReference() {
+		return partList.getActivePartReference();
+	}
+
+	/**
+	 * Returns the active perspective for the page, <code>null</code> if none.
+	 */
+	public Perspective getActivePerspective() {
+		return perspList.getActive();
+	}
+
+	/**
+	 * Returns the client composite.
+	 */
+	public Composite getClientComposite() {
+		return composite;
+	}
+
+	/**
+	 * Answer the perspective presentation.
+	 */
+	public PerspectiveHelper getPerspectivePresentation() {
+		if (getActivePerspective() != null) {
+			return getActivePerspective().getPresentation();
+		}
+		return null;
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IEditorPart[] getEditors() {
+		final IEditorReference refs[] = getEditorReferences();
+		final ArrayList result = new ArrayList(refs.length);
+		Display d = getWorkbenchWindow().getShell().getDisplay();
+		// Must be backward compatible.
+		d.syncExec(new Runnable() {
+			public void run() {
+				for (int i = 0; i < refs.length; i++) {
+					IWorkbenchPart part = refs[i].getPart(true);
+					if (part != null) {
+						result.add(part);
+					}
+				}
+			}
+		});
+		final IEditorPart editors[] = new IEditorPart[result.size()];
+		return (IEditorPart[]) result.toArray(editors);
+	}
+
+	public IEditorPart[] getDirtyEditors() {
+		return new IEditorPart[0];
+	}
+
+	public ISaveablePart[] getDirtyParts() {
+		List result = new ArrayList(3);
+		IWorkbenchPartReference[] allParts = getAllParts();
+		for (int i = 0; i < allParts.length; i++) {
+			IWorkbenchPartReference reference = allParts[i];
+
+			IWorkbenchPart part = reference.getPart(false);
+			if (part != null && part instanceof ISaveablePart) {
+				ISaveablePart saveable = (ISaveablePart) part;
+				if (saveable.isDirty()) {
+					result.add(saveable);
+				}
+			}
+		}
+
+		return (ISaveablePart[]) result
+				.toArray(new ISaveablePart[result.size()]);
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IEditorPart findEditor(IEditorInput input) {
+		IEditorReference[] editorReferences = findEditors(input, null,
+				IWorkbenchPage.MATCH_INPUT);
+		if (editorReferences.length == 0) {
+			return null;
+		}
+		return editorReferences[0].getEditor(true);
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IEditorReference[] findEditors(IEditorInput input, String editorId,
+			int matchFlags) {
+		IEditorReference[] refs = getEditorReferences();
+		ArrayList<IEditorReference> matches = null;
+		for (IEditorReference ref : refs) {
+			if ((matchFlags & IWorkbenchPage.MATCH_ID) != 0) {
+				String testID = ref.getId();
+				if ((editorId != null) && !(editorId.equals(testID)))
+					continue;
+				if (editorId == null && testID != null)
+					continue;
+			}
+			if ((matchFlags & IWorkbenchPage.MATCH_INPUT) != 0) {
+				IEditorInput testInput;
+				try {
+					testInput = ref.getEditorInput();
+				} catch (PartInitException e) {
+					continue;
+				}
+				if ((input != null) && !(input.equals(testInput)))
+					continue;
+				if (input == null && testInput != null)
+					continue;
+			}
+			if (matches == null)
+				matches = new ArrayList<IEditorReference>(3);
+			matches.add(ref);
+		}
+		if (matches == null)
+			return noEditorRefs;
+		IEditorReference[] result = new IEditorReference[matches.size()];
+		matches.toArray(result);
+		return result;
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IEditorReference[] getEditorReferences() {
+		ArrayList<IEditorReference> result = new ArrayList<IEditorReference>();
+		getContainedEditorRefs(result, e4Window);
+		IEditorReference[] typedResult = new IEditorReference[result.size()];
+		result.toArray(typedResult);
+		return typedResult;
+	}
+
+	public void getContainedEditorRefs(ArrayList<IEditorReference> result,
+			MElementContainer<?> container) {
+		for (MUIElement child : container.getChildren()) {
+			if (child instanceof MEditor) {
+				// @issue here we are expected to sort views from editors.
+				// However, there is no such distinction for E4 elements.
+				// The code below is only good for legacy views/editors.
+				Object object = ((MContribution) child).getObject();
+				if (object instanceof EditorPart)
+					result.add(new ModelEditorReference((MPart) child, this));
+			}
+			if (child instanceof MElementContainer<?>)
+				getContainedEditorRefs(result,
+						(MElementContainer<MUIElement>) child);
+		}
+	}
+
+	/**
+	 * Returns the docked views.
+	 */
+	public IViewReference[] getFastViews() {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.getFastViews();
+		} else {
+			return new IViewReference[0];
+		}
+	}
+
+	/**
+	 * @see IWorkbenchPage
+	 */
+	public IAdaptable getInput() {
+		return input;
+	}
+
+	/**
+	 * Returns the page label. This is a combination of the page input and
+	 * active perspective.
+	 */
+	public String getLabel() {
+		String label = WorkbenchMessages.WorkbenchPage_UnknownLabel;
+		IWorkbenchAdapter adapter = (IWorkbenchAdapter) Util.getAdapter(input,
+				IWorkbenchAdapter.class);
+		if (adapter != null) {
+			label = adapter.getLabel(input);
+		}
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
+					label, persp.getDesc().getLabel());
+		} else if (deferredActivePersp != null) {
+			label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
+					label, deferredActivePersp.getLabel());
+		}
+		return label;
+	}
+
+	/**
+	 * Returns the perspective.
+	 */
+	public IPerspectiveDescriptor getPerspective() {
+		if (deferredActivePersp != null) {
+			return deferredActivePersp;
+		}
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.getDesc();
+		} else {
+			return null;
+		}
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionService
+	 */
+	public ISelection getSelection() {
+		return selectionService.getSelection();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionService
+	 */
+	public ISelection getSelection(String partId) {
+		return selectionService.getSelection(partId);
+	}
+
+	/**
+	 * Returns the ids of the parts to list in the Show In... prompter. This is
+	 * a List of Strings.
+	 */
+	public ArrayList getShowInPartIds() {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.getShowInPartIds();
+		} else {
+			return new ArrayList();
+		}
+	}
+
+	/**
+	 * The user successfully performed a Show In... action on the specified
+	 * part. Update the list of Show In items accordingly.
+	 */
+	public void performedShowIn(String partId) {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			persp.performedShowIn(partId);
+		}
+	}
+
+	/**
+	 * Sorts the given collection of show in target part ids in MRU order.
+	 */
+	public void sortShowInPartIds(ArrayList partIds) {
+		final Perspective persp = getActivePerspective();
+		if (persp != null) {
+			Collections.sort(partIds, new Comparator() {
+				public int compare(Object a, Object b) {
+					long ta = persp.getShowInTime((String) a);
+					long tb = persp.getShowInTime((String) b);
+					return (ta == tb) ? 0 : ((ta > tb) ? -1 : 1);
+				}
+			});
+		}
+	}
+
+	/*
+	 * Returns the view factory.
+	 */
+	public ViewFactory getViewFactory() {
+		if (viewFactory == null) {
+			viewFactory = new ViewFactory(this, WorkbenchPlugin.getDefault()
+					.getViewRegistry());
+		}
+		return viewFactory;
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IViewReference[] getViewReferences() {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.getViewReferences();
+		} else {
+			return new IViewReference[0];
+		}
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IViewPart[] getViews() {
+		return getViews(null, true);
+	}
+
+	/**
+	 * Returns all view parts in the specified perspective
+	 * 
+	 * @param persp
+	 *            the perspective
+	 * @return an array of view parts
+	 * @since 3.1
+	 */
+	/* package */IViewPart[] getViews(Perspective persp, boolean restore) {
+		if (persp == null) {
+			persp = getActivePerspective();
+		}
+
+		if (persp != null) {
+			IViewReference refs[] = persp.getViewReferences();
+			ArrayList parts = new ArrayList(refs.length);
+			for (int i = 0; i < refs.length; i++) {
+				IWorkbenchPart part = refs[i].getPart(restore);
+				if (part != null) {
+					parts.add(part);
+				}
+			}
+			IViewPart[] result = new IViewPart[parts.size()];
+			return (IViewPart[]) parts.toArray(result);
+		}
+		return new IViewPart[0];
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IWorkbenchWindow getWorkbenchWindow() {
+		return window;
+	}
+
+	/**
+	 * Implements IWorkbenchPage
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#getWorkingSet()
+	 * @since 2.0
+	 * @deprecated individual views should store a working set if needed
+	 */
+	public IWorkingSet getWorkingSet() {
+		return workingSet;
+	}
+
+	/**
+	 * @see IWorkbenchPage
+	 */
+	public void hideActionSet(String actionSetID) {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			persp.removeActionSet(actionSetID);
+			window.updateActionSets();
+			window.firePerspectiveChanged(this, getPerspective(),
+					CHANGE_ACTION_SET_HIDE);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IWorkbenchPage#hideView(org.eclipse.ui.IViewReference)
+	 */
+	public void hideView(IViewReference ref) {
+
+		// Sanity check.
+		if (ref == null) {
+			return;
+		}
+
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return;
+		}
+
+		IViewPart view = ref.getView(false);
+		if (view != null) {
+
+			if (!certifyPart(view)) {
+				return;
+			}
+
+			// Confirm.
+			if (view instanceof ISaveablePart) {
+				ISaveablePart saveable = (ISaveablePart) view;
+				if (saveable.isSaveOnCloseNeeded()) {
+					IWorkbenchWindow window = view.getSite()
+							.getWorkbenchWindow();
+					boolean success = EditorManager.saveAll(Collections
+							.singletonList(view), true, true, false, window);
+					if (!success) {
+						// the user cancelled.
+						return;
+					}
+				}
+			}
+		}
+
+		// Notify interested listeners before the hide
+		window.firePerspectiveChanged(this, persp.getDesc(), ref,
+				CHANGE_VIEW_HIDE);
+
+		// Hide the part.
+		persp.hideView(ref);
+
+		// Notify interested listeners after the hide
+		window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);
+	}
+
+	/* package */void refreshActiveView() {
+
+	}
+
+	/**
+	 * See IPerspective
+	 */
+	public void hideView(IViewPart view) {
+		hideView((IViewReference) getReference(view));
+	}
+
+	/**
+	 * Initialize the page.
+	 * 
+	 * @param w
+	 *            the parent window
+	 * @param layoutID
+	 *            may be <code>null</code> if restoring from file
+	 * @param input
+	 *            the page input
+	 * @param openExtras
+	 *            whether to process the perspective extras preference
+	 */
+	private void init(WorkbenchWindow w, String layoutID, IAdaptable input,
+			boolean openExtras) throws WorkbenchException {
+		// Save args.
+		this.window = w;
+		this.input = input;
+		actionSets = new ActionSetManager(w);
+
+		e4Window = w.getModelWindow();
+		e4Context = e4Window.getContext();
+		e4Context.set(IWorkbenchPage.class.getName(), this);
+		e4Context.set(WorkbenchPage.class.getName(), this);
+		selectionService = (ISelectionService) e4Context
+				.get(ISelectionService.class.getName());
+		partList = new WorkbenchPagePartList(selectionService);
+
+		navigationHistory = new NavigationHistory(this);
+		e4Context.set(INavigationHistory.class.getName(), navigationHistory);
+
+		((Notifier) e4Window).eAdapters().add(
+				new PartsEventTransformer(e4Context, partList));
+
+		// Create presentation.
+		// Get perspective descriptor.
+		if (layoutID != null) {
+			PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
+					.getDefault().getPerspectiveRegistry()
+					.findPerspectiveWithId(layoutID);
+			if (desc == null) {
+				throw new WorkbenchException(
+						NLS
+								.bind(
+										WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+										layoutID));
+			}
+			Perspective persp = findPerspective(desc);
+			if (persp == null) {
+				persp = createPerspective(desc, true);
+			}
+			perspList.setActive(persp);
+			window.firePerspectiveActivated(this, desc);
+		}
+
+		// read model extensions
+		ModelExtensionProcessor extProcessor = new ModelExtensionProcessor(
+				e4Window);
+		extProcessor.addModelExtensions();
+		partEvents();
+	}
+
+	private void partEvents() {
+		partList.getPartService().addPartListener(new IPartListener() {
+
+			public void partOpened(IWorkbenchPart part) {
+				// TODO Auto-generated method stub
+
+			}
+
+			public void partDeactivated(IWorkbenchPart part) {
+				// TODO Auto-generated method stub
+
+			}
+
+			public void partClosed(IWorkbenchPart part) {
+				// TODO Auto-generated method stub
+
+			}
+
+			public void partBroughtToTop(IWorkbenchPart part) {
+				calculateActionSets(part);
+			}
+
+			public void partActivated(IWorkbenchPart part) {
+				calculateActionSets(part);
+			}
+		});
+	}
+
+	private ArrayList oldActionSets = new ArrayList();
+
+	void calculateActionSets(IWorkbenchPart part) {
+		ArrayList newActionSets = new ArrayList();
+		if (part != null) {
+			IActionSetDescriptor[] partActionSets = WorkbenchPlugin
+					.getDefault().getActionSetRegistry().getActionSetsFor(
+							part.getSite().getId());
+			for (int i = 0; i < partActionSets.length; i++) {
+				newActionSets.add(partActionSets[i]);
+			}
+		}
+		IEditorPart editor = partList.getActiveEditor();
+		if (editor != null && editor != part) {
+			IActionSetDescriptor[] editorActionSets = WorkbenchPlugin
+					.getDefault().getActionSetRegistry().getActionSetsFor(
+							editor.getSite().getId());
+			for (int i = 0; i < editorActionSets.length; i++) {
+				newActionSets.add(editorActionSets[i]);
+			}
+		}
+		if (oldActionSets.equals(newActionSets)) {
+			return;
+		}
+		IContextService service = (IContextService) window
+				.getService(IContextService.class);
+		try {
+			service.deferUpdates(true);
+
+			// show the new
+			for (int i = 0; i < newActionSets.size(); i++) {
+				actionSets.showAction((IActionSetDescriptor) newActionSets
+						.get(i));
+			}
+
+			// hide the old
+			for (int i = 0; i < oldActionSets.size(); i++) {
+				actionSets.hideAction((IActionSetDescriptor) oldActionSets
+						.get(i));
+			}
+
+			oldActionSets = newActionSets;
+
+		} finally {
+			service.deferUpdates(false);
+		}
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return;
+		}
+
+		window.updateActionSets(); // this calls updateActionBars
+		window.firePerspectiveChanged(WorkbenchPage.this, getPerspective(),
+				CHANGE_ACTION_SET_SHOW);
+	}
+
+	/**
+	 * Opens the perspectives specified in the PERSPECTIVE_BAR_EXTRAS preference
+	 * (see bug 84226).
+	 */
+	public void openPerspectiveExtras() {
+		String extras = PrefUtil.getAPIPreferenceStore().getString(
+				IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS);
+		StringTokenizer tok = new StringTokenizer(extras, ", "); //$NON-NLS-1$
+		ArrayList descs = new ArrayList();
+		while (tok.hasMoreTokens()) {
+			String id = tok.nextToken();
+			IPerspectiveDescriptor desc = WorkbenchPlugin.getDefault()
+					.getPerspectiveRegistry().findPerspectiveWithId(id);
+			if (desc != null) {
+				descs.add(desc);
+			}
+		}
+		// HACK: The perspective switcher currently adds the button for a new
+		// perspective to the beginning of the list.
+		// So, we process the extra perspectives in reverse order here to have
+		// their buttons appear in the order declared.
+		for (int i = descs.size(); --i >= 0;) {
+			PerspectiveDescriptor desc = (PerspectiveDescriptor) descs.get(i);
+			if (findPerspective(desc) == null) {
+				createPerspective(desc, true);
+			}
+		}
+	}
+
+	/**
+	 * Finds and returns a part in the current perspective with the
+	 * corresponding id.
+	 * 
+	 * @param partId
+	 *            the id of the part, must not be <code>null</code>
+	 * @return a part in the current perspective with the specified id
+	 */
+	private MPart findPartInCurrentPerspective(String partId) {
+		Assert.isNotNull(partId);
+		// retrieve the perspective stack from our window
+		MPerspectiveStack perspStack = (MPerspectiveStack) ModeledPageLayout
+				.findPart(e4Window, "PerspectiveStack"); //$NON-NLS-1$
+		// get the active/current one
+		MPerspective curPersp = (MPerspective) perspStack.getActiveChild();
+		// try to find a child part
+		return ModeledPageLayout.findPart(curPersp, partId);
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public boolean isPartVisible(IWorkbenchPart part) {
+		if (part == null) {
+			return false;
+		}
+
+		MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
+		// couldn't find the part, return false
+		if (modelPart == null) {
+			return false;
+		}
+
+		MElementContainer<MUIElement> parent = modelPart.getParent();
+		// no parent, probably not visible
+		if (parent == null) {
+			return false;
+		}
+		// return whether the parent's active child is us
+		return parent.getActiveChild() == modelPart;
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public boolean isEditorAreaVisible() {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return false;
+		}
+		return persp.isEditorAreaVisible();
+	}
+
+	/**
+	 * Returns whether the view is fast.
+	 */
+	public boolean isFastView(IViewReference ref) {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.isFastView(ref);
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Return whether the view is closeable or not.
+	 * 
+	 * @param ref
+	 *            the view reference to check. Must not be <code>null</code>.
+	 * @return true if the part is closeable.
+	 * @since 3.1.1
+	 */
+	public boolean isCloseable(IViewReference ref) {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.isCloseable(ref);
+		}
+		return false;
+	}
+
+	/**
+	 * Return whether the view is moveable or not.
+	 * 
+	 * @param ref
+	 *            the view reference to check. Must not be <code>null</code>.
+	 * @return true if the part is moveable.
+	 * @since 3.1.1
+	 */
+	public boolean isMoveable(IViewReference ref) {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.isMoveable(ref);
+		}
+		return false;
+	}
+
+	/**
+	 * Returns whether the layout of the active perspective is fixed.
+	 */
+	public boolean isFixedLayout() {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.isFixedLayout();
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Return the active fast view or null if there are no fast views or if
+	 * there are all minimized.
+	 */
+	public IViewReference getActiveFastView() {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			return persp.getActiveFastView();
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * Return true if the perspective has a dirty editor.
+	 */
+	protected boolean isSaveNeeded() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#isPageZoomed()
+	 */
+	public boolean isPageZoomed() {
+		return false;
+	}
+
+	/**
+	 * Returns whether the page is zoomed.
+	 * 
+	 * @return <code>true</code> if the page is zoomed.
+	 * 
+	 *         <strong>NOTE:</strong> As of 3.3 this method should always return
+	 *         'false' when using the new min/max behavior. It is only used for
+	 *         legacy 'zoom' handling.
+	 * 
+	 */
+	public boolean isZoomed() {
+		return false;
+	}
+
+	/**
+	 * This method is called when the page is activated.
+	 */
+	protected void onActivate() {
+		composite.setVisible(true);
+		Perspective persp = getActivePerspective();
+
+		if (persp != null) {
+			persp.onActivate();
+		}
+	}
+
+	/**
+	 * This method is called when the page is deactivated.
+	 */
+	protected void onDeactivate() {
+		if (getActivePerspective() != null) {
+			getActivePerspective().onDeactivate();
+		}
+		composite.setVisible(false);
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public void reuseEditor(IReusableEditor editor, IEditorInput input) {
+
+		// Rather than calling editor.setInput on the editor directly, we do it
+		// through the part reference.
+		// This case lets us detect badly behaved editors that are not firing a
+		// PROP_INPUT event in response
+		// to the input change... but if all editors obeyed their API contract,
+		// the "else" branch would be
+		// sufficient.
+		IWorkbenchPartReference ref = getReference(editor);
+		if (ref instanceof EditorReference) {
+			EditorReference editorRef = (EditorReference) ref;
+
+			editorRef.setInput(input);
+		} else {
+			editor.setInput(input);
+		}
+		navigationHistory.markEditor(editor);
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IEditorPart openEditor(IEditorInput input, String editorID)
+			throws PartInitException {
+		return openEditor(input, editorID, true, MATCH_INPUT);
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IEditorPart openEditor(IEditorInput input, String editorID,
+			boolean activate) throws PartInitException {
+		return openEditor(input, editorID, activate, MATCH_INPUT);
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IEditorPart openEditor(final IEditorInput input,
+			final String editorID, final boolean activate, final int matchFlags)
+			throws PartInitException {
+		return openEditor(input, editorID, activate, matchFlags, null);
+	}
+
+	/**
+	 * This is not public API but for use internally. editorState can be
+	 * <code>null</code>.
+	 */
+	public IEditorPart openEditor(final IEditorInput input,
+			final String editorID, final boolean activate,
+			final int matchFlags, final IMemento editorState)
+			throws PartInitException {
+		if (input == null || editorID == null) {
+			throw new IllegalArgumentException();
+		}
+
+		// Special handling for external editors (they have no tabs...)
+		if ("org.eclipse.ui.systemExternalEditor".equals(editorID) //$NON-NLS-1$
+				|| "org.eclipse.ui.browser.editorSupport".equals(editorID)) { //$NON-NLS-1$
+			if (input instanceof IPathEditorInput) {
+				IPathEditorInput fileInput = (IPathEditorInput) input;
+				String fullPath = fileInput.getPath().toOSString();
+				Program.launch(fullPath);
+				return null;
+			}
+		}
+
+		// retrieve the editor area
+		MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
+				.internalGetEditorArea());
+
+		// TBD need to add processing for other flags: MATCH_INPUT, MATCH_ID
+		if (matchFlags != IWorkbenchPage.MATCH_NONE) {
+			// Find a matching editor
+			MEditor existingEditor = findEditor(ea, editorID, input);
+			if (existingEditor != null && activate) {
+				// Set the initial focus
+				LegacyEditor le = (LegacyEditor) existingEditor.getObject();
+				Object impl = le.getEditorWBPart();
+				if (impl instanceof IWorkbenchPart) {
+					activate((IWorkbenchPart) impl);
+				} else {
+					ea.setActiveChild(existingEditor);
+				}
+
+				// return the existing editor
+				return (IEditorPart) impl;
+			}
+		}
+
+		// No patching editor found, create one
+		MEditor editorPart = MApplicationFactory.eINSTANCE.createEditor();
+		editorPart.setURI(LegacyEditor.LEGACY_VIEW_URI);
+		editorPart.setId(editorID);
+		editorPart.setName(input.getName());
+		// editor part icon will be set in LegacyViewFactory
+		editorPart.setVisible(false);
+		ea.getChildren().add(editorPart);
+		editorPart.getContext().set(IEditorInput.class.getName(), input);
+		editorPart.setVisible(true);
+
+		// Manage the 'close' button
+		final IEclipseContext editorContext = editorPart.getContext();
+		final MEditor theEditor = editorPart;
+		IValueFunction closeFunc = new IValueFunction() {
+			public Object getValue() {
+				Object impl = ((MPart) theEditor).getObject();
+				if (impl instanceof EditorPart) {
+					EditorPart edPart = (EditorPart) impl;
+					boolean closed = closeEditor(edPart, true);
+					return closed;
+				}
+				return new Boolean(true);
+			}
+		};
+		editorContext.set("canCloseFunc", closeFunc); //$NON-NLS-1$
+
+		LegacyEditor le = (LegacyEditor) editorPart.getObject();
+		Object impl = le.getEditorWBPart();
+		if (impl instanceof IWorkbenchPart) { // TBD this is always the case?
+			IWorkbenchPart workbenchPart = (IWorkbenchPart) impl;
+			if (activate)
+				activate(workbenchPart);
+			else
+				bringToTop(workbenchPart);
+		}
+
+		return le.getEditorWBPart();
+	}
+
+	/**
+	 * @param ea
+	 * @param editorID
+	 * @param input2
+	 * @return
+	 */
+	private MEditor findEditor(MEditorSashContainer ea, String editorID,
+			IEditorInput input) {
+		MUIElement ed = ModeledPageLayout.findElementById(ea, editorID);
+		if (ed instanceof MEditor) {
+			MEditor editor = (MEditor) ed;
+			IEditorInput e = (IEditorInput) editor.getContext().get(
+					IEditorInput.class.getName());
+			if (input.equals(e)) {
+				return editor;
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
+	 * external program. Opens a new editor using the given input and
+	 * descriptor. (Normally, editors are opened using an editor ID and an
+	 * input.)
+	 */
+	public IEditorPart openEditorFromDescriptor(final IEditorInput input,
+			final IEditorDescriptor editorDescriptor, final boolean activate,
+			final IMemento editorState) throws PartInitException {
+		if (input == null || !(editorDescriptor instanceof EditorDescriptor)) {
+			throw new IllegalArgumentException();
+		}
+
+		final IEditorPart result[] = new IEditorPart[1];
+		final PartInitException ex[] = new PartInitException[1];
+		BusyIndicator.showWhile(window.getWorkbench().getDisplay(),
+				new Runnable() {
+					public void run() {
+						try {
+							result[0] = busyOpenEditorFromDescriptor(input,
+									(EditorDescriptor) editorDescriptor,
+									activate, editorState);
+						} catch (PartInitException e) {
+							ex[0] = e;
+						}
+					}
+				});
+		if (ex[0] != null) {
+			throw ex[0];
+		}
+		return result[0];
+	}
+
+	/*
+	 * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
+	 * external program. See openEditorFromDescriptor().
+	 */
+	private IEditorPart busyOpenEditorFromDescriptor(IEditorInput input,
+			EditorDescriptor editorDescriptor, boolean activate,
+			IMemento editorState) throws PartInitException {
+
+		final Workbench workbench = (Workbench) getWorkbenchWindow()
+				.getWorkbench();
+		workbench.largeUpdateStart();
+
+		try {
+			return busyOpenEditorFromDescriptorBatched(input, editorDescriptor,
+					activate, editorState);
+
+		} finally {
+			workbench.largeUpdateEnd();
+		}
+	}
+
+	/**
+	 * Do not call this method. Use <code>busyOpenEditor</code>.
+	 * 
+	 * @see IWorkbenchPage#openEditor(IEditorInput, String, boolean)
+	 */
+	protected IEditorPart busyOpenEditorBatched(IEditorInput input,
+			String editorID, boolean activate, int matchFlags,
+			IMemento editorState) throws PartInitException {
+
+		IEditorPart editor = null;
+		// Otherwise, create a new one. This may cause the new editor to
+		// become the visible (i.e top) editor.
+		IEditorReference ref = null;
+		try {
+			partBeingOpened = true;
+			ref = null; // open the editor, somehow
+			if (ref != null) {
+				editor = ref.getEditor(true);
+			}
+		} finally {
+			partBeingOpened = false;
+		}
+
+		if (editor != null) {
+			setEditorAreaVisible(true);
+			if (activate) {
+				if (editor instanceof AbstractMultiEditor) {
+					activate(((AbstractMultiEditor) editor).getActiveEditor());
+				} else {
+					activate(editor);
+				}
+			} else {
+				bringToTop(editor);
+			}
+			window.firePerspectiveChanged(this, getPerspective(), ref,
+					CHANGE_EDITOR_OPEN);
+			window.firePerspectiveChanged(this, getPerspective(),
+					CHANGE_EDITOR_OPEN);
+		}
+
+		return editor;
+	}
+
+	/*
+	 * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
+	 * external program. See openEditorFromDescriptor().
+	 */
+	private IEditorPart busyOpenEditorFromDescriptorBatched(IEditorInput input,
+			EditorDescriptor editorDescriptor, boolean activate,
+			IMemento editorState) throws PartInitException {
+
+		IEditorPart editor = null;
+		// Create a new one. This may cause the new editor to
+		// become the visible (i.e top) editor.
+		IEditorReference ref = null;
+		ref = null; // open the editor somehow
+		if (ref != null) {
+			editor = ref.getEditor(true);
+		}
+
+		if (editor != null) {
+			setEditorAreaVisible(true);
+			if (activate) {
+				if (editor instanceof AbstractMultiEditor) {
+					activate(((AbstractMultiEditor) editor).getActiveEditor());
+				} else {
+					activate(editor);
+				}
+			} else {
+				bringToTop(editor);
+			}
+			window.firePerspectiveChanged(this, getPerspective(), ref,
+					CHANGE_EDITOR_OPEN);
+			window.firePerspectiveChanged(this, getPerspective(),
+					CHANGE_EDITOR_OPEN);
+		}
+
+		return editor;
+	}
+
+	public void openEmptyTab() {
+
+	}
+
+	protected void showEditor(boolean activate, IEditorPart editor) {
+		setEditorAreaVisible(true);
+		if (activate) {
+			zoomOutIfNecessary(editor);
+			activate(editor);
+		} else {
+			bringToTop(editor);
+		}
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public boolean isEditorPinned(IEditorPart editor) {
+		// TBD we need to add "pinned" attribute somewhere in the E4 model. The
+		// code
+		// below is just to work around a cast class exception
+		IWorkbenchPartReference ref = getReference(editor);
+		if (ref == null)
+			return false;
+		if (ref instanceof WorkbenchPartReference)
+			return ((WorkbenchPartReference) ref).isPinned();
+		return false;
+	}
+
+	/**
+	 * Returns whether changes to a part will affect zoom. There are a few
+	 * conditions for this .. - we are zoomed. - the part is contained in the
+	 * main window. - the part is not the zoom part - the part is not a fast
+	 * view - the part and the zoom part are not in the same editor workbook
+	 */
+	private boolean partChangeAffectsZoom(IWorkbenchPartReference ref) {
+		PartPane pane = ((WorkbenchPartReference) ref).getPane();
+		if (pane instanceof MultiEditorInnerPane) {
+			pane = ((MultiEditorInnerPane) pane).getParentPane();
+		}
+		return getActivePerspective().getPresentation().partChangeAffectsZoom(
+				pane);
+	}
+
+	/**
+	 * Removes a fast view.
+	 */
+	public void removeFastView(IViewReference ref) {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return;
+		}
+
+		// Do real work.
+		persp.removeFastView(ref);
+
+		// Notify listeners.
+		window.firePerspectiveChanged(this, getPerspective(), ref,
+				CHANGE_FAST_VIEW_REMOVE);
+		window.firePerspectiveChanged(this, getPerspective(),
+				CHANGE_FAST_VIEW_REMOVE);
+	}
+
+	/**
+	 * Removes an IPartListener from the part service.
+	 */
+	public void removePartListener(IPartListener l) {
+		partList.getPartService().removePartListener(l);
+	}
+
+	/**
+	 * Removes an IPartListener from the part service.
+	 */
+	public void removePartListener(IPartListener2 l) {
+		partList.getPartService().removePartListener(l);
+	}
+
+	/**
+	 * Implements IWorkbenchPage
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#removePropertyChangeListener(IPropertyChangeListener)
+	 * @since 2.0
+	 * @deprecated individual views should store a working set if needed and
+	 *             register a property change listener directly with the working
+	 *             set manager to receive notification when the view working set
+	 *             is removed.
+	 */
+	public void removePropertyChangeListener(IPropertyChangeListener listener) {
+		propertyChangeListeners.remove(listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void removeSelectionListener(ISelectionListener listener) {
+		selectionService.removeSelectionListener(listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void removeSelectionListener(String partId,
+			ISelectionListener listener) {
+		selectionService.removeSelectionListener(partId, listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void removePostSelectionListener(ISelectionListener listener) {
+		selectionService.removePostSelectionListener(listener);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on ISelectionListener.
+	 */
+	public void removePostSelectionListener(String partId,
+			ISelectionListener listener) {
+		selectionService.removePostSelectionListener(partId, listener);
+	}
+
+	/**
+	 * This method is called when a part is activated by clicking within it. In
+	 * response, the part, the pane, and all of its actions will be activated.
+	 * <p>
+	 * In the current design this method is invoked by the part pane when the
+	 * pane, the part, or any children gain focus.
+	 * </p>
+	 * <p>
+	 * If creating the part causes a forceFocus() well ignore this activation
+	 * request.
+	 * </p>
+	 */
+	public void requestActivation(IWorkbenchPart part) {
+		// Sanity check.
+		if (!certifyPart(part) || partBeingOpened) {
+			return;
+		}
+
+		if (part instanceof AbstractMultiEditor) {
+			part = ((AbstractMultiEditor) part).getActiveEditor();
+		}
+
+		// Real work.
+	}
+
+	/**
+	 * Resets the layout for the perspective. The active part in the old layout
+	 * is activated in the new layout for consistent user context.
+	 */
+	public void resetPerspective() {
+
+	}
+
+	/**
+	 * Restore this page from the memento and ensure that the active perspective
+	 * is equals the active descriptor otherwise create a new perspective for
+	 * that descriptor. If activeDescriptor is null active the old perspective.
+	 */
+	public IStatus restoreState(IMemento memento,
+			final IPerspectiveDescriptor activeDescriptor) {
+		return Status.OK_STATUS;
+	}
+
+	/**
+	 * See IWorkbenchPage
+	 */
+	public boolean saveAllEditors(boolean confirm) {
+		return saveAllEditors(confirm, false);
+	}
+
+	/**
+	 * @param confirm
+	 * @param addNonPartSources
+	 *            true if saveables from non-part sources should be saved too
+	 * @return false if the user cancelled
+	 * 
+	 */
+	public boolean saveAllEditors(boolean confirm, boolean addNonPartSources) {
+		// TBD the code below is oversimplified. See 3.x version for all things
+		// that have to be done:
+		// return getEditorManager().saveAll(confirm, false, addNonPartSources);
+
+		ISaveablePart[] dirtyParts = getDirtyParts();
+		for (ISaveablePart part : dirtyParts) {
+			part.doSave(new NullProgressMonitor());
+		}
+
+		return true;
+	}
+
+	/*
+	 * Saves the workbench part.
+	 */
+	protected boolean savePart(ISaveablePart saveable, IWorkbenchPart part,
+			boolean confirm) {
+		saveable.doSave(new NullProgressMonitor());
+		return true;
+	}
+
+	/**
+	 * Saves an editors in the workbench. If <code>confirm</code> is
+	 * <code>true</code> the user is prompted to confirm the command.
+	 * 
+	 * @param confirm
+	 *            if user confirmation should be sought
+	 * @return <code>true</code> if the command succeeded, or <code>false</code>
+	 *         if the user cancels the command
+	 */
+	public boolean saveEditor(IEditorPart editor, boolean confirm) {
+		return savePart(editor, editor, confirm);
+	}
+
+	/**
+	 * Saves the current perspective.
+	 */
+	public void savePerspective() {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return;
+		}
+
+		// Always unzoom.
+		if (isZoomed()) {
+			zoomOut();
+		}
+
+		persp.saveDesc();
+	}
+
+	/**
+	 * Saves the perspective.
+	 */
+	public void savePerspectiveAs(IPerspectiveDescriptor newDesc) {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return;
+		}
+		IPerspectiveDescriptor oldDesc = persp.getDesc();
+
+		// Always unzoom.
+		if (isZoomed()) {
+			zoomOut();
+		}
+
+		persp.saveDescAs(newDesc);
+		window.firePerspectiveSavedAs(this, oldDesc, newDesc);
+	}
+
+	/**
+	 * Save the state of the page.
+	 */
+	public IStatus saveState(IMemento memento) {
+		// We must unzoom to get correct layout.
+		if (isZoomed()) {
+			zoomOut();
+		}
+
+		// Close any open Fast View
+		hideFastView();
+
+		MultiStatus result = new MultiStatus(
+				PlatformUI.PLUGIN_ID,
+				IStatus.OK,
+				NLS
+						.bind(
+								WorkbenchMessages.WorkbenchPage_unableToSavePerspective,
+								getLabel()), null);
+
+		// Save editor manager.
+		IMemento childMem = memento
+				.createChild(IWorkbenchConstants.TAG_EDITORS);
+		result.merge(editorMgr.saveState(childMem));
+
+		childMem = memento.createChild(IWorkbenchConstants.TAG_VIEWS);
+		result.merge(getViewFactory().saveState(childMem));
+
+		// Create persp block.
+		childMem = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVES);
+		if (getPerspective() != null) {
+			childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE,
+					getPerspective().getId());
+		}
+		if (getActivePart() != null) {
+			if (getActivePart() instanceof IViewPart) {
+				IViewReference ref = (IViewReference) getReference(getActivePart());
+				if (ref != null) {
+					childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
+							ViewFactory.getKey(ref));
+				}
+			} else {
+				childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
+						getActivePart().getSite().getId());
+			}
+		}
+
+		// Save each perspective in opened order
+		Iterator itr = perspList.iterator();
+		while (itr.hasNext()) {
+			Perspective persp = (Perspective) itr.next();
+			IMemento gChildMem = childMem
+					.createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
+			result.merge(persp.saveState(gChildMem));
+		}
+		// Save working set if set
+		if (workingSet != null) {
+			memento.putString(IWorkbenchConstants.TAG_WORKING_SET, workingSet
+					.getName());
+		}
+
+		IMemento workingSetMem = memento
+				.createChild(IWorkbenchConstants.TAG_WORKING_SETS);
+		for (int i = 0; i < workingSets.length; i++) {
+			workingSetMem.createChild(IWorkbenchConstants.TAG_WORKING_SET,
+					workingSets[i].getName());
+		}
+
+		if (aggregateWorkingSetId != null) {
+			memento.putString(ATT_AGGREGATE_WORKING_SET_ID,
+					aggregateWorkingSetId);
+		}
+
+		navigationHistory.saveState(memento
+				.createChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY));
+
+		// save the sticky activation state
+		stickyViewMan.save(memento);
+
+		return result;
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public void setEditorAreaVisible(boolean showEditorArea) {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return;
+		}
+		if (showEditorArea == persp.isEditorAreaVisible()) {
+			return;
+		}
+		// If parts change always update zoom.
+		if (isZoomed()) {
+			zoomOut();
+		}
+		// Update editor area visibility.
+		if (showEditorArea) {
+			persp.showEditorArea();
+			window.firePerspectiveChanged(this, getPerspective(),
+					CHANGE_EDITOR_AREA_SHOW);
+		} else {
+			persp.hideEditorArea();
+			window.firePerspectiveChanged(this, getPerspective(),
+					CHANGE_EDITOR_AREA_HIDE);
+		}
+	}
+
+	/**
+	 * Sets the layout of the page. Assumes the new perspective is not null.
+	 * Keeps the active part if possible. Updates the window menubar and toolbar
+	 * if necessary.
+	 */
+	private void setPerspective(Perspective newPersp) {
+		// Don't do anything if already active layout
+		Perspective oldPersp = getActivePerspective();
+		if (oldPersp == newPersp) {
+			return;
+		}
+
+		window.largeUpdateStart();
+		try {
+			if (oldPersp != null) {
+				// fire the pre-deactivate
+				window.firePerspectivePreDeactivate(this, oldPersp.getDesc());
+			}
+
+			if (newPersp != null) {
+				IStatus status = newPersp.restoreState();
+				if (status.getSeverity() != IStatus.OK) {
+					String title = WorkbenchMessages.WorkbenchPage_problemRestoringTitle;
+					String msg = WorkbenchMessages.WorkbenchPage_errorReadingState;
+					ErrorDialog.openError(getWorkbenchWindow().getShell(),
+							title, msg, status);
+				}
+			}
+
+			// Deactivate the old layout
+			if (oldPersp != null) {
+				oldPersp.onDeactivate();
+
+				// Notify listeners of deactivation
+				window.firePerspectiveDeactivated(this, oldPersp.getDesc());
+			}
+
+			// Activate the new layout
+			perspList.setActive(newPersp);
+			if (newPersp != null) {
+				newPersp.onActivate();
+
+				// Notify listeners of activation
+				window.firePerspectiveActivated(this, newPersp.getDesc());
+			}
+
+			// Update the window
+			window.updateActionSets();
+
+			// Update sticky views
+			stickyViewMan.update(oldPersp, newPersp);
+
+		} finally {
+			window.largeUpdateEnd();
+			if (newPersp == null) {
+				return;
+			}
+			IPerspectiveDescriptor desc = newPersp.getDesc();
+			if (desc == null) {
+				return;
+			}
+			if (dirtyPerspectives.remove(desc.getId())) {
+				suggestReset();
+			}
+		}
+	}
+
+	void perspectiveActionSetChanged(Perspective perspective,
+			IActionSetDescriptor descriptor, int changeType) {
+		if (perspective == getActivePerspective()) {
+			actionSets.change(descriptor, changeType);
+		}
+	}
+
+	/**
+	 * Sets the perspective.
+	 * 
+	 * @param desc
+	 *            identifies the new perspective.
+	 */
+	public void setPerspective(final IPerspectiveDescriptor desc) {
+		try {
+			Perspective oldPersp = getActivePerspective();
+			if ((oldPersp != null)
+					&& oldPersp.getDesc().getId() == desc.getId())
+				return;
+
+			Perspective newPersp = findPerspective(desc);
+			if (newPersp == null) {
+				newPersp = new Perspective((PerspectiveDescriptor) desc, this);
+				perspList.add(newPersp);
+			}
+			// TBD firePerspectivePreDeactivate
+			if (oldPersp != null) {
+				// TBD: exceptions due to null presentations
+				// oldPersp.onDeactivate();
+				// TBD firePerspectiveDeactivated
+			}
+			// Activate the new layout
+			perspList.setActive(newPersp);
+			// also need to let E4 know
+			MPerspective e4perspective = findPerspectiveE4(e4Window, desc
+					.getId());
+			if (e4perspective != null
+					&& e4perspective.getParent().getActiveChild() != e4perspective)
+				e4perspective.getParent().setActiveChild(e4perspective);
+
+			if (newPersp != null) {
+				// TBD exceptions due to null presentations
+				// newPersp.onActivate();
+				// TBD firePerspectiveActivated(this, newPersp.getDesc());
+			}
+		} catch (WorkbenchException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Allow access to the part service for this page ... used internally to
+	 * propogate certain types of events to the page part listeners.
+	 * 
+	 * @return the part service for this page.
+	 */
+	public PartService getPartService() {
+		return (PartService) partList.getPartService();
+	}
+
+	/**
+	 * Restore the toolbar layout for the active perspective.
+	 */
+	protected void resetToolBarLayout() {
+		ICoolBarManager2 mgr = (ICoolBarManager2) window.getCoolBarManager2();
+		mgr.resetItemOrder();
+	}
+
+	/**
+	 * Sets the active working set for the workbench page. Notifies property
+	 * change listener about the change.
+	 * 
+	 * @param newWorkingSet
+	 *            the active working set for the page. May be null.
+	 * @since 2.0
+	 * @deprecated individual views should store a working set if needed
+	 */
+	public void setWorkingSet(IWorkingSet newWorkingSet) {
+		IWorkingSet oldWorkingSet = workingSet;
+
+		workingSet = newWorkingSet;
+		if (oldWorkingSet != newWorkingSet) {
+			firePropertyChange(CHANGE_WORKING_SET_REPLACE, oldWorkingSet,
+					newWorkingSet);
+		}
+		if (newWorkingSet != null) {
+			WorkbenchPlugin
+					.getDefault()
+					.getWorkingSetManager()
+					.addPropertyChangeListener(workingSetPropertyChangeListener);
+		} else {
+			WorkbenchPlugin.getDefault().getWorkingSetManager()
+					.removePropertyChangeListener(
+							workingSetPropertyChangeListener);
+		}
+	}
+
+	/**
+	 * @see IWorkbenchPage
+	 */
+	public void showActionSet(String actionSetID) {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			ActionSetRegistry reg = WorkbenchPlugin.getDefault()
+					.getActionSetRegistry();
+
+			IActionSetDescriptor desc = reg.findActionSet(actionSetID);
+			if (desc != null) {
+				persp.addActionSet(desc);
+				window.updateActionSets();
+				window.firePerspectiveChanged(this, getPerspective(),
+						CHANGE_ACTION_SET_SHOW);
+			}
+		}
+	}
+
+	/**
+	 * See IWorkbenchPage.
+	 */
+	public IViewPart showView(String viewID) throws PartInitException {
+		return showView(viewID, null, VIEW_ACTIVATE);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String,
+	 * java.lang.String, int)
+	 */
+	public IViewPart showView(final String viewID, final String secondaryID,
+			final int mode) throws PartInitException {
+
+		if (secondaryID != null) {
+			if (secondaryID.length() == 0
+					|| secondaryID.indexOf(ViewFactory.ID_SEP) != -1) {
+				throw new IllegalArgumentException(
+						WorkbenchMessages.WorkbenchPage_IllegalSecondaryId);
+			}
+		}
+		if (!certifyMode(mode)) {
+			throw new IllegalArgumentException(
+					WorkbenchMessages.WorkbenchPage_IllegalViewMode);
+		}
+
+		// Run op in busy cursor.
+		final Object[] result = new Object[1];
+		BusyIndicator.showWhile(null, new Runnable() {
+			public void run() {
+				try {
+					result[0] = busyShowView(viewID, secondaryID, mode);
+				} catch (PartInitException e) {
+					result[0] = e;
+				}
+			}
+		});
+		if (result[0] instanceof IViewPart) {
+			return (IViewPart) result[0];
+		} else if (result[0] instanceof PartInitException) {
+			throw (PartInitException) result[0];
+		} else {
+			throw new PartInitException(
+					WorkbenchMessages.WorkbenchPage_AbnormalWorkbenchCondition);
+		}
+	}
+
+	/**
+	 * @param mode
+	 *            the mode to test
+	 * @return whether the mode is recognized
+	 * @since 3.0
+	 */
+	private boolean certifyMode(int mode) {
+		switch (mode) {
+		case VIEW_ACTIVATE:
+		case VIEW_VISIBLE:
+		case VIEW_CREATE:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	/**
+	 * Hides the active fast view. Has no effect if there is no fast view
+	 * active.
+	 */
+	public void hideFastView() {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			IViewReference ref = persp.getActiveFastView();
+			if (ref != null) {
+				toggleFastView(ref);
+			}
+		}
+	}
+
+	/**
+	 * Toggles the visibility of a fast view. If the view is active it is
+	 * deactivated. Otherwise, it is activated.
+	 */
+	public void toggleFastView(IViewReference ref) {
+
+	}
+
+	/**
+	 * Sets the state of the given part.
+	 * 
+	 * @param ref
+	 *            part whose state should be modified (not null)
+	 * @param newState
+	 *            one of the IStackPresentationSite.STATE_* constants
+	 */
+	public void setState(IWorkbenchPartReference ref, int newState) {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return;
+		}
+
+		PartPane pane = ((WorkbenchPartReference) ref).getPane();
+
+		// If target part is detached fire the zoom event. Note this doesn't
+		// actually cause any changes in size and is required to support
+		// intro state changes. We may want to introduce the notion of a zoomed
+		// (fullscreen) detached view at a later time.
+		if (!pane.isDocked()) {
+			pane.setZoomed(newState == IStackPresentationSite.STATE_MAXIMIZED);
+			return;
+		}
+
+		if (ref instanceof IViewReference
+				&& persp.isFastView((IViewReference) ref)) {
+			persp.setFastViewState(newState);
+			return;
+		}
+
+		if (Perspective.useNewMinMax(persp)) {
+			// set the container's state to the new one
+			PartStack parent = ((PartStack) pane.getContainer());
+			parent.setState(newState);
+			return;
+		}
+
+		boolean wasZoomed = isZoomed();
+		boolean isZoomed = newState == IStackPresentationSite.STATE_MAXIMIZED;
+
+		// Update zoom status.
+		if (wasZoomed && !isZoomed) {
+			zoomOut();
+		} else if (!wasZoomed && isZoomed) {
+			persp.getPresentation().zoomIn(ref);
+			activate(ref.getPart(true));
+		}
+
+		PartStack parent = ((PartStack) pane.getContainer());
+
+		if (parent != null) {
+			parent
+					.setMinimized(newState == IStackPresentationSite.STATE_MINIMIZED);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seeorg.eclipse.ui.IWorkbenchPage#setPartState(org.eclipse.ui.
+	 * IWorkbenchPartReference, int)
+	 */
+	public void setPartState(IWorkbenchPartReference ref, int state) {
+		setState(ref, state);
+	}
+
+	/**
+	 * Returns the maximized/minimized/restored state of the given part
+	 * reference
+	 * 
+	 * @param ref
+	 *            part to query (not null)
+	 * @return one of the IStackPresentationSite.STATE_* constants
+	 */
+	int getState(IWorkbenchPartReference ref) {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return IStackPresentationSite.STATE_RESTORED;
+		}
+
+		// TBD concept not yet implemented in E4
+		if (!(ref instanceof WorkbenchPartReference))
+			return IStackPresentationSite.STATE_RESTORED;
+
+		PartPane pane = ((WorkbenchPartReference) ref).getPane();
+
+		if (ref instanceof IViewReference
+				&& persp.isFastView((IViewReference) ref)) {
+			return persp.getFastViewState();
+		}
+
+		PartStack parent = ((PartStack) pane.getContainer());
+
+		if (parent != null) {
+			return parent.getState();
+		}
+
+		return IStackPresentationSite.STATE_RESTORED;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seeorg.eclipse.ui.IWorkbenchPage#getPartState(org.eclipse.ui.
+	 * IWorkbenchPartReference)
+	 */
+	public int getPartState(IWorkbenchPartReference ref) {
+		return getState(ref);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @seeorg.eclipse.ui.IWorkbenchPage#toggleZoom(org.eclipse.ui.
+	 * IWorkbenchPartReference)
+	 */
+	public void toggleZoom(IWorkbenchPartReference ref) {
+		int oldState = getState(ref);
+		boolean shouldZoom = oldState != IStackPresentationSite.STATE_MAXIMIZED;
+		int newState = shouldZoom ? IStackPresentationSite.STATE_MAXIMIZED
+				: IStackPresentationSite.STATE_RESTORED;
+
+		setState(ref, newState);
+	}
+
+	/**
+	 * updateActionBars method comment.
+	 */
+	public void updateActionBars() {
+		window.updateActionBars();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#zoomOut()
+	 */
+	public void zoomOut() {
+		Perspective persp = getActivePerspective();
+		if (persp != null) {
+			persp.getPresentation().zoomOut();
+		}
+	}
+
+	/**
+	 * Zooms out a zoomed in part if it is necessary to do so for the user to
+	 * view the IWorkbenchPart that is the argument. Otherwise, does nothing.
+	 * 
+	 * @param part
+	 *            the part to be made viewable
+	 */
+	private void zoomOutIfNecessary(IWorkbenchPart part) {
+		if (isZoomed()
+				&& partChangeAffectsZoom(((PartSite) part.getSite())
+						.getPartReference())) {
+			zoomOut();
+		}
+	}
+
+	/**
+     * 
+     */
+	public int getEditorReuseThreshold() {
+		return ((TabBehaviour) Tweaklets.get(TabBehaviour.KEY))
+				.getEditorReuseThreshold();
+	}
+
+	/**
+     * 
+     */
+	public void setEditorReuseThreshold(int openEditors) {
+	}
+
+	/*
+	 * Returns the editors in activation order (oldest first).
+	 */
+	public IEditorReference[] getSortedEditors() {
+		return getEditorReferences();
+	}
+
+	/**
+	 * @see IWorkbenchPage#getOpenPerspectives()
+	 */
+	public IPerspectiveDescriptor[] getOpenPerspectives() {
+		Perspective opened[] = perspList.getOpenedPerspectives();
+		IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[opened.length];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = opened[i].getDesc();
+		}
+		return result;
+	}
+
+	/**
+	 * Return all open Perspective objects.
+	 * 
+	 * @return all open Perspective objects
+	 * @since 3.1
+	 */
+	/* package */Perspective[] getOpenInternalPerspectives() {
+		return perspList.getOpenedPerspectives();
+	}
+
+	/**
+	 * Checks perspectives in the order they were activiated for the specfied
+	 * part. The first sorted perspective that contains the specified part is
+	 * returned.
+	 * 
+	 * @param part
+	 *            specified part to search for
+	 * @return the first sorted perspespective containing the part
+	 * @since 3.1
+	 */
+	/* package */Perspective getFirstPerspectiveWithView(IViewPart part) {
+		Perspective[] perspectives = perspList.getSortedPerspectives();
+		for (int i = perspectives.length - 1; i >= 0; i--) {
+			if (perspectives[i].containsView(part)) {
+				return perspectives[i];
+			}
+		}
+		// we should never get here
+		return null;
+	}
+
+	/**
+	 * Returns the perspectives in activation order (oldest first).
+	 */
+	public IPerspectiveDescriptor[] getSortedPerspectives() {
+		Perspective sortedArray[] = perspList.getSortedPerspectives();
+		IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[sortedArray.length];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = sortedArray[i].getDesc();
+		}
+		return result;
+	}
+
+	/*
+	 * Returns the parts in activation order (oldest first).
+	 */
+	public IWorkbenchPartReference[] getSortedParts() {
+		return new IWorkbenchPartReference[0];
+	}
+
+	/**
+	 * Returns the reference to the given part, or <code>null</code> if it has
+	 * no reference (i.e. it is not a top-level part in this workbench page).
+	 * 
+	 * @param part
+	 *            the part
+	 * @return the part's reference or <code>null</code> if the given part does
+	 *         not belong to this workbench page
+	 */
+	public IWorkbenchPartReference getReference(IWorkbenchPart part) {
+		if (part == null) {
+			return null;
+		}
+		IWorkbenchPartSite site = part.getSite();
+		if (!(site instanceof PartSite)) {
+			return null;
+		}
+		PartSite partSite = ((PartSite) site);
+		PartPane pane = partSite.getPane();
+		if (pane instanceof MultiEditorInnerPane) {
+			MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
+			return innerPane.getParentPane().getPartReference();
+		}
+		return partSite.getPartReference();
+	}
+
+	/**
+	 * Helper class to keep track of all opened perspective. Both the opened and
+	 * used order is kept.
+	 */
+	private class PerspectiveList {
+		/**
+		 * List of perspectives in the order they were opened;
+		 */
+		private List openedList;
+
+		/**
+		 * List of perspectives in the order they were used. Last element is the
+		 * most recently used, and first element is the least recently used.
+		 */
+		private List usedList;
+
+		/**
+		 * The perspective explicitly set as being the active one
+		 */
+		private Perspective active;
+
+		/**
+		 * Creates an empty instance of the perspective list
+		 */
+		public PerspectiveList() {
+			openedList = new ArrayList();
+			usedList = new ArrayList();
+		}
+
+		/**
+		 * Return all perspectives in the order they were activated.
+		 * 
+		 * @return an array of perspectives sorted by activation order, least
+		 *         recently activated perspective last.
+		 */
+		public Perspective[] getSortedPerspectives() {
+			Perspective[] result = new Perspective[usedList.size()];
+			return (Perspective[]) usedList.toArray(result);
+		}
+
+		/**
+		 * Adds a perspective to the list. No check is done for a duplicate when
+		 * adding.
+		 * 
+		 * @param perspective
+		 *            the perspective to add
+		 * @return boolean <code>true</code> if the perspective was added
+		 */
+		public boolean add(Perspective perspective) {
+			openedList.add(perspective);
+			usedList.add(0, perspective);
+			// It will be moved to top only when activated.
+			return true;
+		}
+
+		/**
+		 * Returns an iterator on the perspective list in the order they were
+		 * opened.
+		 */
+		public Iterator iterator() {
+			return openedList.iterator();
+		}
+
+		/**
+		 * Returns an array with all opened perspectives
+		 */
+		public Perspective[] getOpenedPerspectives() {
+			Perspective[] result = new Perspective[openedList.size()];
+			return (Perspective[]) openedList.toArray(result);
+		}
+
+		/**
+		 * Returns whether the list contains any perspectives
+		 */
+		public boolean isEmpty() {
+			return openedList.isEmpty();
+		}
+
+		/**
+		 * Returns the most recently used perspective in the list.
+		 */
+		public Perspective getActive() {
+			return active;
+		}
+
+		/**
+		 * Marks the specified perspective as the most recently used one in the
+		 * list.
+		 */
+		public void setActive(Perspective perspective) {
+			if (perspective == active) {
+				return;
+			}
+
+			updateActionSets(active, perspective);
+			active = perspective;
+
+			if (perspective != null) {
+				usedList.remove(perspective);
+				usedList.add(perspective);
+			}
+		}
+
+		private void updateActionSets(Perspective oldPersp, Perspective newPersp) {
+			// Update action sets
+
+			IContextService service = (IContextService) window
+					.getService(IContextService.class);
+			try {
+				service.deferUpdates(true);
+				if (newPersp != null) {
+					IActionSetDescriptor[] newAlwaysOn = newPersp
+							.getAlwaysOnActionSets();
+					for (int i = 0; i < newAlwaysOn.length; i++) {
+						IActionSetDescriptor descriptor = newAlwaysOn[i];
+
+						actionSets.showAction(descriptor);
+					}
+
+					IActionSetDescriptor[] newAlwaysOff = newPersp
+							.getAlwaysOffActionSets();
+					for (int i = 0; i < newAlwaysOff.length; i++) {
+						IActionSetDescriptor descriptor = newAlwaysOff[i];
+
+						actionSets.maskAction(descriptor);
+					}
+				}
+
+				if (oldPersp != null) {
+					IActionSetDescriptor[] newAlwaysOn = oldPersp
+							.getAlwaysOnActionSets();
+					for (int i = 0; i < newAlwaysOn.length; i++) {
+						IActionSetDescriptor descriptor = newAlwaysOn[i];
+
+						actionSets.hideAction(descriptor);
+					}
+
+					IActionSetDescriptor[] newAlwaysOff = oldPersp
+							.getAlwaysOffActionSets();
+					for (int i = 0; i < newAlwaysOff.length; i++) {
+						IActionSetDescriptor descriptor = newAlwaysOff[i];
+
+						actionSets.unmaskAction(descriptor);
+					}
+				}
+			} finally {
+				service.deferUpdates(false);
+			}
+		}
+	}
+
+	// for dynamic UI
+	protected void addPerspective(Perspective persp) {
+		perspList.add(persp);
+		window.firePerspectiveOpened(this, persp.getDesc());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#getViewStack(org.eclipse.ui.IViewPart)
+	 */
+	public IViewPart[] getViewStack(IViewPart part) {
+		// check to make sure this part is in the current perspective
+		MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
+		if (modelPart == null) {
+			// if not, return null
+			return null;
+		}
+
+		List<IViewPart> stack = new ArrayList<IViewPart>();
+		// retrieve the parent stack
+		MElementContainer<MUIElement> viewStack = modelPart.getParent();
+		// get the contents of the stack
+		for (MUIElement child : viewStack.getChildren()) {
+			if (child instanceof MContribution) {
+				Object object = ((MContribution) child).getObject();
+				// queue it up if it's a view
+				if (object instanceof IViewPart) {
+					stack.add((IViewPart) object);
+				}
+			}
+		}
+		return stack.toArray(new IViewPart[stack.size()]);
+	}
+
+	/**
+	 * Allow for programmatically resizing a part.
+	 * <p>
+	 * <em>EXPERIMENTAL</em>
+	 * </p>
+	 * <p>
+	 * Known limitations:
+	 * <ul>
+	 * <li>currently applies only to views</li>
+	 * <li>has no effect when view is zoomed</li>
+	 * </ul>
+	 */
+	public void resizeView(IViewPart part, int width, int height) {
+		SashInfo sashInfo = new SashInfo();
+		PartPane pane = ((PartSite) part.getSite()).getPane();
+		ILayoutContainer container = pane.getContainer();
+		LayoutTree tree = getPerspectivePresentation().getLayout().root
+				.find(((ViewStack) container));
+
+		// retrieve our layout sashes from the layout tree
+		findSashParts(tree, pane.findSashes(), sashInfo);
+
+		// first set the width
+		float deltaWidth = width - pane.getBounds().width;
+		if (sashInfo.right != null) {
+			Rectangle rightBounds = sashInfo.rightNode.getBounds();
+			// set the new ratio
+			sashInfo.right
+					.setRatio(((deltaWidth + sashInfo.right.getBounds().x) - rightBounds.x)
+							/ rightBounds.width);
+			// complete the resize
+			sashInfo.rightNode.setBounds(rightBounds);
+		} else if (sashInfo.left != null) {
+			Rectangle leftBounds = sashInfo.leftNode.getBounds();
+			// set the ratio
+			sashInfo.left
+					.setRatio(((sashInfo.left.getBounds().x - deltaWidth) - leftBounds.x)
+							/ leftBounds.width);
+			// complete the resize
+			sashInfo.leftNode.setBounds(sashInfo.leftNode.getBounds());
+		}
+
+		// next set the height
+		float deltaHeight = height - pane.getBounds().height;
+		if (sashInfo.bottom != null) {
+			Rectangle bottomBounds = sashInfo.bottomNode.getBounds();
+			// set the new ratio
+			sashInfo.bottom.setRatio(((deltaHeight + sashInfo.bottom
+					.getBounds().y) - bottomBounds.y)
+					/ bottomBounds.height);
+			// complete the resize
+			sashInfo.bottomNode.setBounds(bottomBounds);
+		} else if (sashInfo.top != null) {
+			Rectangle topBounds = sashInfo.topNode.getBounds();
+			// set the ratio
+			sashInfo.top
+					.setRatio(((sashInfo.top.getBounds().y - deltaHeight) - topBounds.y)
+							/ topBounds.height);
+			// complete the resize
+			sashInfo.topNode.setBounds(topBounds);
+		}
+
+	}
+
+	// provides sash information for the given pane
+	private class SashInfo {
+		private LayoutPartSash right;
+
+		private LayoutPartSash left;
+
+		private LayoutPartSash top;
+
+		private LayoutPartSash bottom;
+
+		private LayoutTreeNode rightNode;
+
+		private LayoutTreeNode leftNode;
+
+		private LayoutTreeNode topNode;
+
+		private LayoutTreeNode bottomNode;
+	}
+
+	private void findSashParts(LayoutTree tree, PartPane.Sashes sashes,
+			SashInfo info) {
+		LayoutTree parent = tree.getParent();
+		if (parent == null) {
+			return;
+		}
+
+		if (parent.part instanceof LayoutPartSash) {
+			// get the layout part sash from this tree node
+			LayoutPartSash sash = (LayoutPartSash) parent.part;
+			// make sure it has a sash control
+			Control control = sash.getControl();
+			if (control != null) {
+				// check for a vertical sash
+				if (sash.isVertical()) {
+					if (sashes.left == control) {
+						info.left = sash;
+						info.leftNode = parent.findSash(sash);
+					} else if (sashes.right == control) {
+						info.right = sash;
+						info.rightNode = parent.findSash(sash);
+					}
+				}
+				// check for a horizontal sash
+				else {
+					if (sashes.top == control) {
+						info.top = sash;
+						info.topNode = parent.findSash(sash);
+					} else if (sashes.bottom == control) {
+						info.bottom = sash;
+						info.bottomNode = parent.findSash(sash);
+					}
+				}
+			}
+		}
+		// recursive call to continue up the tree
+		findSashParts(parent, sashes, info);
+	}
+
+	/**
+	 * Returns all parts that are owned by this page
+	 * 
+	 * @return all open parts, including non-participating editors.
+	 */
+	IWorkbenchPartReference[] getAllParts() {
+		ArrayList<IWorkbenchPartReference> result = new ArrayList<IWorkbenchPartReference>();
+		getContainedPartRefs(result, e4Window);
+		IWorkbenchPartReference[] typedResult = new IWorkbenchPartReference[result
+				.size()];
+		result.toArray(typedResult);
+		return typedResult;
+	}
+
+	// TBD this code repeats multiple times in variations (get editors, get
+	// views, get parts). When typically callers filter them some more (isDirty,
+	// isVisble, etc.).
+	// This needs to be a generic utility
+	private void getContainedPartRefs(
+			ArrayList<IWorkbenchPartReference> result,
+			MElementContainer<?> container) {
+		for (MUIElement child : container.getChildren()) {
+			if (child instanceof MPart) {
+				MPart contributedChild = (MPart) child;
+				if (contributedChild.isVisible()) {
+					Object object = contributedChild.getObject();
+					if (object instanceof IWorkbenchPart)
+						result.add(new ModelReference(contributedChild, this));
+				}
+			}
+			if (child instanceof MElementContainer<?>)
+				getContainedPartRefs(result, (MElementContainer<?>) child);
+		}
+	}
+
+	/**
+	 * Returns all open parts that are owned by this page (that is, all parts
+	 * for which a part opened event would have been sent -- these would be
+	 * activated parts whose controls have already been created.
+	 */
+	IWorkbenchPartReference[] getOpenParts() {
+		IWorkbenchPartReference[] refs = getAllParts();
+		List result = new ArrayList();
+
+		for (int i = 0; i < refs.length; i++) {
+			IWorkbenchPartReference reference = refs[i];
+
+			IWorkbenchPart part = reference.getPart(false);
+			if (part != null) {
+				result.add(reference);
+			}
+		}
+
+		return (IWorkbenchPartReference[]) result
+				.toArray(new IWorkbenchPartReference[result.size()]);
+	}
+
+	/**
+	 * Sanity-checks the objects in this page. Throws an Assertation exception
+	 * if an object's internal state is invalid. ONLY INTENDED FOR USE IN THE UI
+	 * TEST SUITES.
+	 */
+	public void testInvariants() {
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#getExtensionTracker()
+	 */
+	public IExtensionTracker getExtensionTracker() {
+		if (tracker == null) {
+			tracker = new UIExtensionTracker(getWorkbenchWindow()
+					.getWorkbench().getDisplay());
+		}
+		return tracker;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#getNewWizardShortcuts()
+	 */
+	public String[] getNewWizardShortcuts() {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return new String[0];
+		}
+		return persp.getNewWizardShortcuts();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#getPerspectiveShortcuts()
+	 */
+	public String[] getPerspectiveShortcuts() {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return new String[0];
+		}
+		return persp.getPerspectiveShortcuts();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPage#getShowViewShortcuts()
+	 */
+	public String[] getShowViewShortcuts() {
+		Perspective persp = getActivePerspective();
+		if (persp == null) {
+			return new String[0];
+		}
+		return persp.getShowViewShortcuts();
+	}
+
+	/**
+	 * @since 3.1
+	 */
+	private void suggestReset() {
+		final IWorkbench workbench = getWorkbenchWindow().getWorkbench();
+		workbench.getDisplay().asyncExec(new Runnable() {
+			public void run() {
+				Shell parentShell = null;
+
+				IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+				if (window == null) {
+					if (workbench.getWorkbenchWindowCount() == 0) {
+						return;
+					}
+					window = workbench.getWorkbenchWindows()[0];
+				}
+
+				parentShell = window.getShell();
+
+				if (MessageDialog.openQuestion(parentShell,
+						WorkbenchMessages.Dynamic_resetPerspectiveTitle,
+						WorkbenchMessages.Dynamic_resetPerspectiveMessage)) {
+					IWorkbenchPage page = window.getActivePage();
+					if (page == null) {
+						return;
+					}
+					page.resetPerspective();
+				}
+			}
+		});
+
+	}
+
+	public boolean isPartVisible(IWorkbenchPartReference reference) {
+		IWorkbenchPart part = reference.getPart(false);
+		// Can't be visible if it isn't created yet
+		if (part == null) {
+			return false;
+		}
+
+		return isPartVisible(part);
+	}
+
+	public IWorkingSet[] getWorkingSets() {
+		return workingSets;
+	}
+
+	public void setWorkingSets(IWorkingSet[] newWorkingSets) {
+		if (newWorkingSets != null) {
+			WorkbenchPlugin
+					.getDefault()
+					.getWorkingSetManager()
+					.addPropertyChangeListener(workingSetPropertyChangeListener);
+		} else {
+			WorkbenchPlugin.getDefault().getWorkingSetManager()
+					.removePropertyChangeListener(
+							workingSetPropertyChangeListener);
+		}
+
+		if (newWorkingSets == null) {
+			newWorkingSets = new IWorkingSet[0];
+		}
+
+		IWorkingSet[] oldWorkingSets = workingSets;
+
+		// filter out any duplicates if necessary
+		if (newWorkingSets.length > 1) {
+			Set setOfSets = new HashSet();
+			for (int i = 0; i < newWorkingSets.length; i++) {
+				if (newWorkingSets[i] == null) {
+					throw new IllegalArgumentException();
+				}
+				setOfSets.add(newWorkingSets[i]);
+			}
+			newWorkingSets = (IWorkingSet[]) setOfSets
+					.toArray(new IWorkingSet[setOfSets.size()]);
+		}
+
+		workingSets = newWorkingSets;
+		if (!Arrays.equals(oldWorkingSets, newWorkingSets)) {
+			firePropertyChange(CHANGE_WORKING_SETS_REPLACE, oldWorkingSets,
+					newWorkingSets);
+			if (aggregateWorkingSet != null) {
+				aggregateWorkingSet.setComponents(workingSets);
+			}
+		}
+	}
+
+	public IWorkingSet getAggregateWorkingSet() {
+		if (aggregateWorkingSet == null) {
+			IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
+					.getWorkingSetManager();
+			aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
+					.getWorkingSet(getAggregateWorkingSetId());
+			if (aggregateWorkingSet == null) {
+				aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
+						.createAggregateWorkingSet(
+								getAggregateWorkingSetId(),
+								WorkbenchMessages.WorkbenchPage_workingSet_default_label,
+								getWorkingSets());
+				workingSetManager.addWorkingSet(aggregateWorkingSet);
+			}
+		}
+		return aggregateWorkingSet;
+	}
+
+	private String getAggregateWorkingSetId() {
+		if (aggregateWorkingSetId == null) {
+			aggregateWorkingSetId = "Aggregate for window " + System.currentTimeMillis(); //$NON-NLS-1$
+		}
+		return aggregateWorkingSetId;
+	}
+
+	public void showEditor(IEditorReference ref) {
+	}
+
+	public void hideEditor(IEditorReference ref) {
+		// partList.removePart((WorkbenchPartReference)ref);
+	}
+
+	public IEditorReference[] openEditors(final IEditorInput[] inputs,
+			final String[] editorIDs, final int matchFlags)
+			throws MultiPartInitException {
+		if (inputs == null)
+			throw new IllegalArgumentException();
+		if (editorIDs == null)
+			throw new IllegalArgumentException();
+		if (inputs.length != editorIDs.length)
+			throw new IllegalArgumentException();
+
+		ArrayList refs = new ArrayList();
+
+		for (int i = 0; i < inputs.length; i++) {
+			IEditorPart ed = null;
+			try {
+				// brute force approach
+				ed = openEditor(inputs[i], editorIDs[i], true, matchFlags);
+			} catch (PartInitException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			if (ed != null) {
+				refs.add(((PartSite) ed.getSite()).getPartReference());
+			}
+		}
+
+		return (IEditorReference[]) refs.toArray(new IEditorReference[refs
+				.size()]);
+	}
+
+	public void resetHiddenEditors() {
+		IEditorReference[] refs = (IEditorReference[]) removedEditors
+				.toArray(new IEditorReference[removedEditors.size()]);
+		for (int i = 0; i < refs.length; i++) {
+			showEditor(refs[i]);
+		}
+	}
+
+	public MWindow getModelWindow() {
+		return e4Window;
+	}
+
+	// TBD this code repeats multiple times in variations (get editors, get
+	// views, get parts). When typically callers filter them some more (isDirty,
+	// isVisble, etc.).
+	// This needs to be a generic utility
+	private MPerspective findPerspectiveE4(MWindow e4Window, String id) {
+		MUIElement pe = ModeledPageLayout.findElementById(e4Window, id);
+		if (pe instanceof MPerspective)
+			return (MPerspective) pe;
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPagePartList.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPagePartList.java
new file mode 100644
index 0000000..12b25b8
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPagePartList.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+
+public class WorkbenchPagePartList extends PartList {
+
+	private PartService partService = new PartService(
+			UIListenerLogging.PAGE_PARTLISTENER_EVENTS,
+			UIListenerLogging.PAGE_PARTLISTENER2_EVENTS);
+
+	public WorkbenchPagePartList(ISelectionService selectionService) {
+	}
+
+	public IPartService getPartService() {
+		return partService;
+	}
+
+	protected void firePartOpened(IWorkbenchPartReference part) {
+		partService.firePartOpened(part);
+	}
+
+	protected void firePartClosed(IWorkbenchPartReference part) {
+		partService.firePartClosed(part);
+	}
+
+	protected void firePartAdded(IWorkbenchPartReference part) {
+		// TODO: There is no listener for workbench page additions yet
+	}
+
+	protected void firePartRemoved(IWorkbenchPartReference part) {
+		// TODO: There is no listener for workbench page removals yet
+	}
+
+	protected void fireActiveEditorChanged(IWorkbenchPartReference ref) {
+		if (ref != null) {
+			firePartBroughtToTop(ref);
+		}
+	}
+
+	protected void fireActivePartChanged(IWorkbenchPartReference oldRef,
+			IWorkbenchPartReference newRef) {
+		partService.setActivePart(newRef);
+
+	}
+
+	protected void firePartHidden(IWorkbenchPartReference ref) {
+		partService.firePartHidden(ref);
+	}
+
+	protected void firePartVisible(IWorkbenchPartReference ref) {
+		partService.firePartVisible(ref);
+	}
+
+	protected void firePartInputChanged(IWorkbenchPartReference ref) {
+		partService.firePartInputChanged(ref);
+	}
+
+	public void firePartBroughtToTop(IWorkbenchPartReference ref) {
+		partService.firePartBroughtToTop(ref);
+	}
+
+	protected void firePageChanged(PageChangedEvent event) {
+		partService.firePageChanged(event);
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPlugin.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPlugin.java
new file mode 100644
index 0000000..83fee54
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPlugin.java
@@ -0,0 +1,1471 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import com.ibm.icu.text.MessageFormat;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Locale;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.IPerspectiveRegistry;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.decorators.DecoratorManager;
+import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceManager;
+import org.eclipse.ui.internal.intro.IIntroRegistry;
+import org.eclipse.ui.internal.intro.IntroRegistry;
+import org.eclipse.ui.internal.misc.StatusUtil;
+import org.eclipse.ui.internal.operations.WorkbenchOperationSupport;
+import org.eclipse.ui.internal.progress.ProgressManager;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.EditorRegistry;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.PerspectiveRegistry;
+import org.eclipse.ui.internal.registry.PreferencePageRegistryReader;
+import org.eclipse.ui.internal.registry.ViewRegistry;
+import org.eclipse.ui.internal.registry.WorkingSetRegistry;
+import org.eclipse.ui.internal.themes.IThemeRegistry;
+import org.eclipse.ui.internal.themes.ThemeRegistry;
+import org.eclipse.ui.internal.themes.ThemeRegistryReader;
+import org.eclipse.ui.internal.util.BundleUtility;
+import org.eclipse.ui.internal.wizards.ExportWizardRegistry;
+import org.eclipse.ui.internal.wizards.ImportWizardRegistry;
+import org.eclipse.ui.internal.wizards.NewWizardRegistry;
+import org.eclipse.ui.operations.IWorkbenchOperationSupport;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.presentations.AbstractPresentationFactory;
+import org.eclipse.ui.views.IViewRegistry;
+import org.eclipse.ui.wizards.IWizardRegistry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * This class represents the TOP of the workbench UI world A plugin class is
+ * effectively an org.eclipse.e4.ui.model.application wrapper for a plugin & its classes. This class
+ * should be thought of as the workbench UI's org.eclipse.e4.ui.model.application class.
+ * 
+ * This class is responsible for tracking various registries font, preference,
+ * graphics, dialog store.
+ * 
+ * This class is explicitly referenced by the workbench plugin's "plugin.xml"
+ * and places it into the UI start extension point of the main overall
+ * org.eclipse.e4.ui.model.application harness
+ * 
+ * When is this class started? When the Application calls
+ * createExecutableExtension to create an executable instance of our workbench
+ * class.
+ */
+public class WorkbenchPlugin extends AbstractUIPlugin {
+
+	/**
+	 * Splash shell constant.
+	 */
+	private static final String DATA_SPLASH_SHELL = "org.eclipse.ui.workbench.splashShell"; //$NON-NLS-1$
+
+	/**
+	 * The OSGi splash property.
+	 * 
+	 * @since 3.4
+	 */
+	private static final String PROP_SPLASH_HANDLE = "org.eclipse.equinox.launcher.splash.handle"; //$NON-NLS-1$
+
+	private static final String LEFT_TO_RIGHT = "ltr"; //$NON-NLS-1$
+	private static final String RIGHT_TO_LEFT = "rtl";//$NON-NLS-1$
+	private static final String ORIENTATION_COMMAND_LINE = "-dir";//$NON-NLS-1$
+	private static final String ORIENTATION_PROPERTY = "eclipse.orientation";//$NON-NLS-1$
+	private static final String NL_USER_PROPERTY = "osgi.nl.user"; //$NON-NLS-1$
+
+	// Default instance of the receiver
+	private static WorkbenchPlugin inst;
+
+	// Manager that maps resources to descriptors of editors to use
+	private EditorRegistry editorRegistry;
+
+	// Manager for the DecoratorManager
+	private DecoratorManager decoratorManager;
+
+	// Theme registry
+	private ThemeRegistry themeRegistry;
+
+	// Manager for working sets (IWorkingSet)
+	private WorkingSetManager workingSetManager;
+
+	// Working set registry, stores working set dialogs
+	private WorkingSetRegistry workingSetRegistry;
+
+	// The context within which this plugin was started.
+	private BundleContext bundleContext;
+
+	// The set of currently starting bundles
+	private Collection startingBundles = new HashSet();
+
+	/**
+	 * Global workbench ui plugin flag. Only workbench implementation is allowed
+	 * to use this flag All other plugins, examples, or test cases must *not*
+	 * use this flag.
+	 */
+	public static boolean DEBUG = false;
+
+	/**
+	 * The workbench plugin ID.
+	 * 
+	 * @issue we should just drop this constant and use PlatformUI.PLUGIN_ID
+	 *        instead
+	 */
+	public static String PI_WORKBENCH = PlatformUI.PLUGIN_ID;
+
+	/**
+	 * The character used to separate preference page category ids
+	 */
+	public static char PREFERENCE_PAGE_CATEGORY_SEPARATOR = '/';
+
+	// Other data.
+	private WorkbenchPreferenceManager preferenceManager;
+
+	private ViewRegistry viewRegistry;
+
+	private PerspectiveRegistry perspRegistry;
+
+	private ActionSetRegistry actionSetRegistry;
+
+	private SharedImages sharedImages;
+
+	/**
+	 * Information describing the product (formerly called "primary plugin");
+	 * lazily initialized.
+	 * 
+	 * @since 3.0
+	 */
+	private ProductInfo productInfo = null;
+
+	private IntroRegistry introRegistry;
+
+	private WorkbenchOperationSupport operationSupport;
+	private BundleListener bundleListener;
+
+	private IEclipseContext e4Context;
+
+	/**
+	 * Create an instance of the WorkbenchPlugin. The workbench plugin is
+	 * effectively the "org.eclipse.e4.ui.model.application" for the workbench UI. The entire UI
+	 * operates as a good plugin citizen.
+	 */
+	public WorkbenchPlugin() {
+		super();
+		inst = this;
+	}
+
+	/**
+	 * Unload all members. This can be used to run a second instance of a
+	 * workbench.
+	 * 
+	 * @since 3.0
+	 */
+	void reset() {
+		editorRegistry = null;
+
+		if (decoratorManager != null) {
+			decoratorManager.dispose();
+			decoratorManager = null;
+		}
+
+		ProgressManager.shutdownProgressManager();
+
+		themeRegistry = null;
+		if (workingSetManager != null) {
+			workingSetManager.dispose();
+			workingSetManager = null;
+		}
+		workingSetRegistry = null;
+
+		preferenceManager = null;
+		if (viewRegistry != null) {
+			viewRegistry.dispose();
+			viewRegistry = null;
+		}
+		if (perspRegistry != null) {
+			perspRegistry.dispose();
+			perspRegistry = null;
+		}
+		actionSetRegistry = null;
+		sharedImages = null;
+
+		productInfo = null;
+		introRegistry = null;
+
+		if (operationSupport != null) {
+			operationSupport.dispose();
+			operationSupport = null;
+		}
+
+		DEBUG = false;
+
+	}
+
+	/**
+	 * Creates an extension. If the extension plugin has not been loaded a busy
+	 * cursor will be activated during the duration of the load.
+	 * 
+	 * @param element
+	 *            the config element defining the extension
+	 * @param classAttribute
+	 *            the name of the attribute carrying the class
+	 * @return the extension object
+	 * @throws CoreException
+	 *             if the extension cannot be created
+	 */
+	public static Object createExtension(final IConfigurationElement element,
+			final String classAttribute) throws CoreException {
+		try {
+			// If plugin has been loaded create extension.
+			// Otherwise, show busy cursor then create extension.
+			if (BundleUtility.isActivated(element.getDeclaringExtension()
+					.getNamespace())) {
+				return element.createExecutableExtension(classAttribute);
+			}
+			final Object[] ret = new Object[1];
+			final CoreException[] exc = new CoreException[1];
+			BusyIndicator.showWhile(null, new Runnable() {
+				public void run() {
+					try {
+						ret[0] = element
+								.createExecutableExtension(classAttribute);
+					} catch (CoreException e) {
+						exc[0] = e;
+					}
+				}
+			});
+			if (exc[0] != null) {
+				throw exc[0];
+			}
+			return ret[0];
+
+		} catch (CoreException core) {
+			throw core;
+		} catch (Exception e) {
+			throw new CoreException(new Status(IStatus.ERROR, PI_WORKBENCH,
+					IStatus.ERROR, WorkbenchMessages.WorkbenchPlugin_extension,
+					e));
+		}
+	}
+
+	/**
+	 * Answers whether the provided element either has an attribute with the
+	 * given name or a child element with the given name with an attribute
+	 * called class.
+	 * 
+	 * @param element
+	 *            the element to test
+	 * @param extensionName
+	 *            the name of the extension to test for
+	 * @return whether or not the extension is declared
+	 * @since 3.3
+	 */
+	public static boolean hasExecutableExtension(IConfigurationElement element,
+			String extensionName) {
+
+		if (element.getAttribute(extensionName) != null)
+			return true;
+		String elementText = element.getValue();
+		if (elementText != null && !elementText.equals("")) //$NON-NLS-1$
+			return true;
+		IConfigurationElement[] children = element.getChildren(extensionName);
+		if (children.length == 1) {
+			if (children[0].getAttribute(IWorkbenchRegistryConstants.ATT_CLASS) != null)
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Checks to see if the provided element has the syntax for an executable
+	 * extension with a given name that resides in a bundle that is already
+	 * active. Determining the bundle happens in one of two ways:<br/>
+	 * <ul>
+	 * <li>The element has an attribute with the specified name or element text
+	 * in the form <code>bundle.id/class.name[:optional attributes]</code></li>
+	 * <li>The element has a child element with the specified name that has a
+	 * <code>plugin</code> attribute</li>
+	 * </ul>
+	 * 
+	 * @param element
+	 *            the element to test
+	 * @param extensionName
+	 *            the name of the extension to test for
+	 * @return whether or not the bundle expressed by the above criteria is
+	 *         active. If the bundle cannot be determined then the state of the
+	 *         bundle that declared the element is returned.
+	 * @since 3.3
+	 */
+	public static boolean isBundleLoadedForExecutableExtension(
+			IConfigurationElement element, String extensionName) {
+		Bundle bundle = getBundleForExecutableExtension(element, extensionName);
+
+		if (bundle == null)
+			return true;
+		return bundle.getState() == Bundle.ACTIVE;
+	}
+
+	/**
+	 * Returns the bundle that contains the class referenced by an executable
+	 * extension. Determining the bundle happens in one of two ways:<br/>
+	 * <ul>
+	 * <li>The element has an attribute with the specified name or element text
+	 * in the form <code>bundle.id/class.name[:optional attributes]</code></li>
+	 * <li>The element has a child element with the specified name that has a
+	 * <code>plugin</code> attribute</li>
+	 * </ul>
+	 * 
+	 * @param element
+	 *            the element to test
+	 * @param extensionName
+	 *            the name of the extension to test for
+	 * @return the bundle referenced by the extension. If that bundle cannot be
+	 *         determined the bundle that declared the element is returned. Note
+	 *         that this may be <code>null</code>.
+	 * @since 3.3
+	 */
+	public static Bundle getBundleForExecutableExtension(
+			IConfigurationElement element, String extensionName) {
+		// this code is derived heavily from
+		// ConfigurationElement.createExecutableExtension.
+		String prop = null;
+		String executable;
+		String contributorName = null;
+		int i;
+
+		if (extensionName != null)
+			prop = element.getAttribute(extensionName);
+		else {
+			// property not specified, try as element value
+			prop = element.getValue();
+			if (prop != null) {
+				prop = prop.trim();
+				if (prop.equals("")) //$NON-NLS-1$
+					prop = null;
+			}
+		}
+
+		if (prop == null) {
+			// property not defined, try as a child element
+			IConfigurationElement[] exec = element.getChildren(extensionName);
+			if (exec.length != 0)
+				contributorName = exec[0].getAttribute("plugin"); //$NON-NLS-1$
+		} else {
+			// simple property or element value, parse it into its components
+			i = prop.indexOf(':');
+			if (i != -1)
+				executable = prop.substring(0, i).trim();
+			else
+				executable = prop;
+
+			i = executable.indexOf('/');
+			if (i != -1)
+				contributorName = executable.substring(0, i).trim();
+
+		}
+
+		if (contributorName == null)
+			contributorName = element.getContributor().getName();
+
+		return Platform.getBundle(contributorName);
+	}
+
+	/**
+	 * Returns the image registry for this plugin.
+	 * 
+	 * Where are the images? The images (typically gifs) are found in the same
+	 * plugins directory.
+	 * 
+	 * @see ImageRegistry
+	 * 
+	 *      Note: The workbench uses the standard JFace ImageRegistry to track
+	 *      its images. In addition the class WorkbenchGraphicResources provides
+	 *      convenience access to the graphics resources and fast field access
+	 *      for some of the commonly used graphical images.
+	 */
+	protected ImageRegistry createImageRegistry() {
+		return WorkbenchImages.getImageRegistry();
+	}
+
+	/**
+	 * Returns the action set registry for the workbench.
+	 * 
+	 * @return the workbench action set registry
+	 */
+	public ActionSetRegistry getActionSetRegistry() {
+		return (ActionSetRegistry) e4Context.get(ActionSetRegistry.class
+				.getName());
+	}
+
+	/**
+	 * Return the default instance of the receiver. This represents the runtime
+	 * plugin.
+	 * 
+	 * @return WorkbenchPlugin
+	 * @see AbstractUIPlugin for the typical implementation pattern for plugin
+	 *      classes.
+	 */
+	public static WorkbenchPlugin getDefault() {
+		return inst;
+	}
+
+	/**
+	 * Answer the manager that maps resource types to a the description of the
+	 * editor to use
+	 * 
+	 * @return IEditorRegistry the editor registry used by this plug-in.
+	 */
+
+	public IEditorRegistry getEditorRegistry() {
+		return (IEditorRegistry) e4Context.get(IEditorRegistry.class.getName());
+	}
+
+	/**
+	 * Answer the element factory for an id, or <code>null</code. if not found.
+	 * 
+	 * @param targetID
+	 * @return IElementFactory
+	 */
+	public IElementFactory getElementFactory(String targetID) {
+
+		// Get the extension point registry.
+		IExtensionPoint extensionPoint;
+		extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(
+				PI_WORKBENCH, IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY);
+
+		if (extensionPoint == null) {
+			WorkbenchPlugin
+					.log("Unable to find element factory. Extension point: " + IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY + " not found"); //$NON-NLS-2$ //$NON-NLS-1$
+			return null;
+		}
+
+		// Loop through the config elements.
+		IConfigurationElement targetElement = null;
+		IConfigurationElement[] configElements = extensionPoint
+				.getConfigurationElements();
+		for (int j = 0; j < configElements.length; j++) {
+			String strID = configElements[j].getAttribute("id"); //$NON-NLS-1$
+			if (targetID.equals(strID)) {
+				targetElement = configElements[j];
+				break;
+			}
+		}
+		if (targetElement == null) {
+			// log it since we cannot safely display a dialog.
+			WorkbenchPlugin.log("Unable to find element factory: " + targetID); //$NON-NLS-1$
+			return null;
+		}
+
+		// Create the extension.
+		IElementFactory factory = null;
+		try {
+			factory = (IElementFactory) createExtension(targetElement, "class"); //$NON-NLS-1$
+		} catch (CoreException e) {
+			// log it since we cannot safely display a dialog.
+			WorkbenchPlugin.log(
+					"Unable to create element factory.", e.getStatus()); //$NON-NLS-1$
+			factory = null;
+		}
+		return factory;
+	}
+
+	/**
+	 * Returns the presentation factory with the given id, or <code>null</code>
+	 * if not found.
+	 * 
+	 * @param targetID
+	 *            The id of the presentation factory to use.
+	 * @return AbstractPresentationFactory or <code>null</code> if not factory
+	 *         matches that id.
+	 */
+	public AbstractPresentationFactory getPresentationFactory(String targetID) {
+		Object o = createExtension(
+				IWorkbenchRegistryConstants.PL_PRESENTATION_FACTORIES,
+				"factory", targetID); //$NON-NLS-1$
+		if (o instanceof AbstractPresentationFactory) {
+			return (AbstractPresentationFactory) o;
+		}
+		WorkbenchPlugin
+				.log("Error creating presentation factory: " + targetID + " -- class is not an AbstractPresentationFactory"); //$NON-NLS-1$ //$NON-NLS-2$
+		return null;
+	}
+
+	/**
+	 * Looks up the configuration element with the given id on the given
+	 * extension point and instantiates the class specified by the class
+	 * attributes.
+	 * 
+	 * @param extensionPointId
+	 *            the extension point id (simple id)
+	 * @param elementName
+	 *            the name of the configuration element, or <code>null</code> to
+	 *            match any element
+	 * @param targetID
+	 *            the target id
+	 * @return the instantiated extension object, or <code>null</code> if not
+	 *         found
+	 */
+	private Object createExtension(String extensionPointId, String elementName,
+			String targetID) {
+		IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+				.getExtensionPoint(PI_WORKBENCH, extensionPointId);
+		if (extensionPoint == null) {
+			WorkbenchPlugin
+					.log("Unable to find extension. Extension point: " + extensionPointId + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
+			return null;
+		}
+
+		// Loop through the config elements.
+		IConfigurationElement targetElement = null;
+		IConfigurationElement[] elements = extensionPoint
+				.getConfigurationElements();
+		for (int j = 0; j < elements.length; j++) {
+			IConfigurationElement element = elements[j];
+			if (elementName == null || elementName.equals(element.getName())) {
+				String strID = element.getAttribute("id"); //$NON-NLS-1$
+				if (targetID.equals(strID)) {
+					targetElement = element;
+					break;
+				}
+			}
+		}
+		if (targetElement == null) {
+			// log it since we cannot safely display a dialog.
+			WorkbenchPlugin.log("Unable to find extension: " + targetID //$NON-NLS-1$
+					+ " in extension point: " + extensionPointId); //$NON-NLS-1$ 
+			return null;
+		}
+
+		// Create the extension.
+		try {
+			return createExtension(targetElement, "class"); //$NON-NLS-1$
+		} catch (CoreException e) {
+			// log it since we cannot safely display a dialog.
+			WorkbenchPlugin.log("Unable to create extension: " + targetID //$NON-NLS-1$
+					+ " in extension point: " + extensionPointId //$NON-NLS-1$
+					+ ", status: ", e.getStatus()); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	/**
+	 * Return the perspective registry.
+	 * 
+	 * @return IPerspectiveRegistry. The registry for the receiver.
+	 */
+	public IPerspectiveRegistry getPerspectiveRegistry() {
+		if (perspRegistry == null) {
+			perspRegistry = new PerspectiveRegistry();
+			// the load methods can touch on WorkbenchImages if
+			// an image is
+			// missing so we need to wrap the call in
+			// a startup block for the case where a custom
+			// descriptor exists on
+			// startup that does not have an image
+			// associated with it. See bug 196352.
+			StartupThreading.runWithoutExceptions(new StartupRunnable() {
+				public void runWithException() throws Throwable {
+					perspRegistry.load();
+				}
+			});
+
+		}
+		return perspRegistry;
+	}
+
+	/**
+	 * Returns the working set manager
+	 * 
+	 * @return the working set manager
+	 * @since 2.0
+	 */
+	public IWorkingSetManager getWorkingSetManager() {
+		return (IWorkingSetManager) e4Context.get(IWorkingSetManager.class
+				.getName());
+	}
+
+	/**
+	 * Returns the working set registry
+	 * 
+	 * @return the working set registry
+	 * @since 2.0
+	 */
+	public WorkingSetRegistry getWorkingSetRegistry() {
+		return (WorkingSetRegistry) e4Context.get(WorkingSetRegistry.class
+				.getName());
+	}
+
+	/**
+	 * Returns the introduction registry.
+	 * 
+	 * @return the introduction registry.
+	 * @since 3.0
+	 */
+	public IIntroRegistry getIntroRegistry() {
+		return (IIntroRegistry) e4Context.get(IIntroRegistry.class.getName());
+	}
+
+	/**
+	 * Returns the operation support.
+	 * 
+	 * @return the workbench operation support.
+	 * @since 3.1
+	 */
+	public IWorkbenchOperationSupport getOperationSupport() {
+		return (IWorkbenchOperationSupport) e4Context
+				.get(IWorkbenchOperationSupport.class.getName());
+	}
+
+	/**
+	 * Get the preference manager.
+	 * 
+	 * @return PreferenceManager the preference manager for the receiver.
+	 */
+	public PreferenceManager getPreferenceManager() {
+		return (PreferenceManager) e4Context.get(PreferenceManager.class
+				.getName());
+	}
+
+	/**
+	 * Returns the shared images for the workbench.
+	 * 
+	 * @return the shared image manager
+	 */
+	public ISharedImages getSharedImages() {
+		return (ISharedImages) e4Context.get(ISharedImages.class.getName());
+	}
+
+	/**
+	 * Returns the theme registry for the workbench.
+	 * 
+	 * @return the theme registry
+	 */
+	public IThemeRegistry getThemeRegistry() {
+		return (IThemeRegistry) e4Context.get(IThemeRegistry.class.getName());
+	}
+
+	/**
+	 * Answer the view registry.
+	 * 
+	 * @return IViewRegistry the view registry for the receiver.
+	 */
+	public IViewRegistry getViewRegistry() {
+		return (IViewRegistry) e4Context.get(IViewRegistry.class.getName());
+	}
+
+	/**
+	 * Answer the workbench.
+	 * 
+	 * @deprecated Use <code>PlatformUI.getWorkbench()</code> instead.
+	 */
+	public IWorkbench getWorkbench() {
+		return PlatformUI.getWorkbench();
+	}
+
+	/**
+	 * Set default preference values. This method must be called whenever the
+	 * preference store is initially loaded because the default values are not
+	 * stored in the preference store.
+	 */
+	protected void initializeDefaultPreferences(IPreferenceStore store) {
+		// Do nothing. This should not be called.
+		// Prefs are initialized in WorkbenchPreferenceInitializer.
+	}
+
+	/**
+	 * Logs the given message to the platform log.
+	 * 
+	 * If you have an exception in hand, call log(String, Throwable) instead.
+	 * 
+	 * If you have a status object in hand call log(String, IStatus) instead.
+	 * 
+	 * This convenience method is for internal use by the Workbench only and
+	 * must not be called outside the Workbench.
+	 * 
+	 * @param message
+	 *            A high level UI message describing when the problem happened.
+	 */
+	public static void log(String message) {
+		getDefault().getLog().log(
+				StatusUtil.newStatus(IStatus.ERROR, message, null));
+	}
+
+	/**
+	 * Log the throwable.
+	 * 
+	 * @param t
+	 */
+	public static void log(Throwable t) {
+		getDefault().getLog().log(getStatus(t));
+	}
+
+	/**
+	 * Return the status from throwable
+	 * 
+	 * @param t
+	 *            throwable
+	 * @return IStatus
+	 */
+	public static IStatus getStatus(Throwable t) {
+		String message = StatusUtil.getLocalizedMessage(t);
+
+		return newError(message, t);
+	}
+
+	/**
+	 * Create a new error from the message and the throwable.
+	 * 
+	 * @param message
+	 * @param t
+	 * @return IStatus
+	 */
+	public static IStatus newError(String message, Throwable t) {
+		String pluginId = "org.eclipse.ui.workbench"; //$NON-NLS-1$
+		int errorCode = IStatus.OK;
+
+		// If this was a CoreException, keep the original plugin ID and error
+		// code
+		if (t instanceof CoreException) {
+			CoreException ce = (CoreException) t;
+			pluginId = ce.getStatus().getPlugin();
+			errorCode = ce.getStatus().getCode();
+		}
+
+		return new Status(IStatus.ERROR, pluginId, errorCode, message,
+				StatusUtil.getCause(t));
+	}
+
+	/**
+	 * Logs the given message and throwable to the platform log.
+	 * 
+	 * If you have a status object in hand call log(String, IStatus) instead.
+	 * 
+	 * This convenience method is for internal use by the Workbench only and
+	 * must not be called outside the Workbench.
+	 * 
+	 * @param message
+	 *            A high level UI message describing when the problem happened.
+	 * @param t
+	 *            The throwable from where the problem actually occurred.
+	 */
+	public static void log(String message, Throwable t) {
+		IStatus status = StatusUtil.newStatus(IStatus.ERROR, message, t);
+		log(message, status);
+	}
+
+	/**
+	 * Logs the given throwable to the platform log, indicating the class and
+	 * method from where it is being logged (this is not necessarily where it
+	 * occurred).
+	 * 
+	 * This convenience method is for internal use by the Workbench only and
+	 * must not be called outside the Workbench.
+	 * 
+	 * @param clazz
+	 *            The calling class.
+	 * @param methodName
+	 *            The calling method name.
+	 * @param t
+	 *            The throwable from where the problem actually occurred.
+	 */
+	public static void log(Class clazz, String methodName, Throwable t) {
+		String msg = MessageFormat.format("Exception in {0}.{1}: {2}", //$NON-NLS-1$
+				new Object[] { clazz.getName(), methodName, t });
+		log(msg, t);
+	}
+
+	/**
+	 * Logs the given message and status to the platform log.
+	 * 
+	 * This convenience method is for internal use by the Workbench only and
+	 * must not be called outside the Workbench.
+	 * 
+	 * @param message
+	 *            A high level UI message describing when the problem happened.
+	 *            May be <code>null</code>.
+	 * @param status
+	 *            The status describing the problem. Must not be null.
+	 */
+	public static void log(String message, IStatus status) {
+
+		// 1FTUHE0: ITPCORE:ALL - API - Status & logging - loss of semantic info
+
+		if (message != null) {
+			getDefault().getLog().log(
+					StatusUtil.newStatus(IStatus.ERROR, message, null));
+		}
+
+		getDefault().getLog().log(status);
+	}
+
+	/**
+	 * Log the status to the default log.
+	 * 
+	 * @param status
+	 */
+	public static void log(IStatus status) {
+		getDefault().getLog().log(status);
+	}
+
+	/**
+	 * Get the decorator manager for the receiver
+	 * 
+	 * @return DecoratorManager the decorator manager for the receiver.
+	 */
+	public DecoratorManager getDecoratorManager() {
+		return (DecoratorManager) e4Context.get(IDecoratorManager.class
+				.getName());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
+	 * )
+	 */
+	public void start(BundleContext context) throws Exception {
+		context.addBundleListener(getBundleListener());
+		super.start(context);
+		bundleContext = context;
+
+		JFaceUtil.initializeJFace();
+
+		Window.setDefaultOrientation(getDefaultOrientation());
+
+		// The UI plugin needs to be initialized so that it can install the
+		// callback in PrefUtil,
+		// which needs to be done as early as possible, before the workbench
+		// accesses any API preferences.
+		Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
+		try {
+			// Attempt to load the activator of the ui bundle. This will force
+			// lazy start
+			// of the ui bundle. Using the bundle activator class here because
+			// it is a
+			// class that needs to be loaded anyway so it should not cause extra
+			// classes
+			// to be loaded.s
+			if (uiBundle != null)
+				uiBundle.start(Bundle.START_TRANSIENT);
+		} catch (BundleException e) {
+			WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$
+		}
+		/*
+		 * DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are
+		 * likely to cause a deadlock in class loader code. Please see Bug 86450
+		 * for more information.
+		 */
+
+	}
+
+	/**
+	 * Get the default orientation from the command line arguments. If there are
+	 * no arguments imply the orientation.
+	 * 
+	 * @return int
+	 * @see SWT#NONE
+	 * @see SWT#RIGHT_TO_LEFT
+	 * @see SWT#LEFT_TO_RIGHT
+	 */
+	private int getDefaultOrientation() {
+
+		String[] commandLineArgs = Platform.getCommandLineArgs();
+
+		int orientation = getCommandLineOrientation(commandLineArgs);
+
+		if (orientation != SWT.NONE) {
+			return orientation;
+		}
+
+		orientation = getSystemPropertyOrientation();
+
+		if (orientation != SWT.NONE) {
+			return orientation;
+		}
+
+		return checkCommandLineLocale(); // Use the default value if there is
+		// nothing specified
+	}
+
+	/**
+	 * Check to see if the command line parameter for -nl has been set. If so
+	 * imply the orientation from this specified Locale. If it is a
+	 * bidirectional Locale return SWT#RIGHT_TO_LEFT. If it has not been set or
+	 * has been set to a unidirectional Locale then return SWT#NONE.
+	 * 
+	 * Locale is determined differently by different JDKs and may not be
+	 * consistent with the users expectations.
+	 * 
+	 * 
+	 * @return int
+	 * @see SWT#NONE
+	 * @see SWT#RIGHT_TO_LEFT
+	 */
+	private int checkCommandLineLocale() {
+
+		// Check if the user property is set. If not do not
+		// rely on the vm.
+		if (System.getProperty(NL_USER_PROPERTY) == null) {
+			return SWT.NONE;
+		}
+
+		Locale locale = Locale.getDefault();
+		String lang = locale.getLanguage();
+
+		if ("iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				"fa".equals(lang) || "ur".equals(lang)) { //$NON-NLS-1$ //$NON-NLS-2$ 
+			return SWT.RIGHT_TO_LEFT;
+		}
+
+		return SWT.NONE;
+	}
+
+	/**
+	 * Check to see if the orientation was set in the system properties. If
+	 * there is no orientation specified return SWT#NONE.
+	 * 
+	 * @return int
+	 * @see SWT#NONE
+	 * @see SWT#RIGHT_TO_LEFT
+	 * @see SWT#LEFT_TO_RIGHT
+	 */
+	private int getSystemPropertyOrientation() {
+		String orientation = System.getProperty(ORIENTATION_PROPERTY);
+		if (RIGHT_TO_LEFT.equals(orientation)) {
+			return SWT.RIGHT_TO_LEFT;
+		}
+		if (LEFT_TO_RIGHT.equals(orientation)) {
+			return SWT.LEFT_TO_RIGHT;
+		}
+		return SWT.NONE;
+	}
+
+	/**
+	 * Find the orientation in the commandLineArgs. If there is no orientation
+	 * specified return SWT#NONE.
+	 * 
+	 * @param commandLineArgs
+	 * @return int
+	 * @see SWT#NONE
+	 * @see SWT#RIGHT_TO_LEFT
+	 * @see SWT#LEFT_TO_RIGHT
+	 */
+	private int getCommandLineOrientation(String[] commandLineArgs) {
+		// Do not process the last one as it will never have a parameter
+		for (int i = 0; i < commandLineArgs.length - 1; i++) {
+			if (commandLineArgs[i].equalsIgnoreCase(ORIENTATION_COMMAND_LINE)) {
+				String orientation = commandLineArgs[i + 1];
+				if (orientation.equals(RIGHT_TO_LEFT)) {
+					System.setProperty(ORIENTATION_PROPERTY, RIGHT_TO_LEFT);
+					return SWT.RIGHT_TO_LEFT;
+				}
+				if (orientation.equals(LEFT_TO_RIGHT)) {
+					System.setProperty(ORIENTATION_PROPERTY, LEFT_TO_RIGHT);
+					return SWT.LEFT_TO_RIGHT;
+				}
+			}
+		}
+
+		return SWT.NONE;
+	}
+
+	/**
+	 * Return an array of all bundles contained in this workbench.
+	 * 
+	 * @return an array of bundles in the workbench or an empty array if none
+	 * @since 3.0
+	 */
+	public Bundle[] getBundles() {
+		return bundleContext == null ? new Bundle[0] : bundleContext
+				.getBundles();
+	}
+
+	/**
+	 * Returns the bundle context associated with the workbench plug-in.
+	 * 
+	 * @return the bundle context
+	 * @since 3.1
+	 */
+	public BundleContext getBundleContext() {
+		return bundleContext;
+	}
+
+	/**
+	 * Returns the org.eclipse.e4.ui.model.application name.
+	 * <p>
+	 * Note this is never shown to the user. It is used to initialize the SWT
+	 * Display. On Motif, for example, this can be used to set the name used for
+	 * resource lookup.
+	 * </p>
+	 * 
+	 * @return the org.eclipse.e4.ui.model.application name, or <code>null</code>
+	 * @see org.eclipse.swt.widgets.Display#setAppName
+	 * @since 3.0
+	 */
+	public String getAppName() {
+		return getProductInfo().getAppName();
+	}
+
+	/**
+	 * Returns the name of the product.
+	 * 
+	 * @return the product name, or <code>null</code> if none
+	 * @since 3.0
+	 */
+	public String getProductName() {
+		return getProductInfo().getProductName();
+	}
+
+	/**
+	 * Returns the image descriptors for the window image to use for this
+	 * product.
+	 * 
+	 * @return an array of the image descriptors for the window image, or
+	 *         <code>null</code> if none
+	 * @since 3.0
+	 */
+	public ImageDescriptor[] getWindowImages() {
+		return getProductInfo().getWindowImages();
+	}
+
+	/**
+	 * Returns an instance that describes this plugin's product (formerly
+	 * "primary plugin").
+	 * 
+	 * @return ProductInfo the product info for the receiver
+	 */
+	private ProductInfo getProductInfo() {
+		if (productInfo == null) {
+			productInfo = new ProductInfo(Platform.getProduct());
+		}
+		return productInfo;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+	 * )
+	 */
+	public void stop(BundleContext context) throws Exception {
+		if (bundleListener != null) {
+			context.removeBundleListener(bundleListener);
+			bundleListener = null;
+		}
+		// TODO normally super.stop(*) would be the last statement in this
+		// method
+		super.stop(context);
+	}
+
+	/**
+	 * Return the new wizard registry.
+	 * 
+	 * @return the new wizard registry
+	 * @since 3.1
+	 */
+	public IWizardRegistry getNewWizardRegistry() {
+		return (IWizardRegistry) e4Context.get(NewWizardRegistry.class
+				.getName());
+	}
+
+	/**
+	 * Return the import wizard registry.
+	 * 
+	 * @return the import wizard registry
+	 * @since 3.1
+	 */
+	public IWizardRegistry getImportWizardRegistry() {
+		return (IWizardRegistry) e4Context.get(ImportWizardRegistry.class
+				.getName());
+	}
+
+	/**
+	 * Return the export wizard registry.
+	 * 
+	 * @return the export wizard registry
+	 * @since 3.1
+	 */
+	public IWizardRegistry getExportWizardRegistry() {
+		return (IWizardRegistry) e4Context.get(ExportWizardRegistry.class
+				.getName());
+	}
+
+	/**
+	 * FOR INTERNAL WORKBENCH USE ONLY.
+	 * 
+	 * Returns the path to a location in the file system that can be used to
+	 * persist/restore state between workbench invocations. If the location did
+	 * not exist prior to this call it will be created. Returns
+	 * <code>null</code> if no such location is available.
+	 * 
+	 * @return path to a location in the file system where this plug-in can
+	 *         persist data between sessions, or <code>null</code> if no such
+	 *         location is available.
+	 * @since 3.1
+	 */
+	public IPath getDataLocation() {
+		try {
+			return getStateLocation();
+		} catch (IllegalStateException e) {
+			// This occurs if -data=@none is explicitly specified, so ignore
+			// this silently.
+			// Is this OK? See bug 85071.
+			return null;
+		}
+	}
+
+	/* package */void addBundleListener(BundleListener bundleListener) {
+		bundleContext.addBundleListener(bundleListener);
+	}
+
+	/* package */void removeBundleListener(BundleListener bundleListener) {
+		bundleContext.removeBundleListener(bundleListener);
+	}
+
+	/* package */int getBundleCount() {
+		return bundleContext.getBundles().length;
+	}
+
+	/* package */OutputStream getSplashStream() {
+		// assumes the output stream is available as a service
+		// see EclipseStarter.publishSplashScreen
+		ServiceReference[] ref;
+		try {
+			ref = bundleContext.getServiceReferences(OutputStream.class
+					.getName(), null);
+		} catch (InvalidSyntaxException e) {
+			return null;
+		}
+		if (ref == null) {
+			return null;
+		}
+		for (int i = 0; i < ref.length; i++) {
+			String name = (String) ref[i].getProperty("name"); //$NON-NLS-1$
+			if (name != null && name.equals("splashstream")) { //$NON-NLS-1$
+				Object result = bundleContext.getService(ref[i]);
+				bundleContext.ungetService(ref[i]);
+				return (OutputStream) result;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @return
+	 */
+	private BundleListener getBundleListener() {
+		if (bundleListener == null) {
+			bundleListener = new SynchronousBundleListener() {
+				public void bundleChanged(BundleEvent event) {
+					WorkbenchPlugin.this.bundleChanged(event);
+				}
+			};
+		}
+		return bundleListener;
+	}
+
+	private void bundleChanged(BundleEvent event) {
+		// a bundle in the STARTING state generates 2 events, LAZY_ACTIVATION
+		// when it enters STARTING and STARTING when it exists STARTING :-)
+		synchronized (startingBundles) {
+			switch (event.getType()) {
+			case BundleEvent.STARTING:
+				startingBundles.add(event.getBundle());
+				break;
+			case BundleEvent.STARTED:
+			case BundleEvent.STOPPED:
+				startingBundles.remove(event.getBundle());
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	public boolean isStarting(Bundle bundle) {
+		synchronized (startingBundles) {
+			return startingBundles.contains(bundle);
+		}
+	}
+
+	/**
+	 * Return whether or not the OSGi framework has specified the handle of a
+	 * splash shell.
+	 * 
+	 * @return whether or not the OSGi framework has specified the handle of a
+	 *         splash shell
+	 * @since 3.4
+	 */
+	public static boolean isSplashHandleSpecified() {
+		return System.getProperty(PROP_SPLASH_HANDLE) != null;
+	}
+
+	/**
+	 * Get the splash shell for this workbench instance, if any. This will find
+	 * the splash created by the launcher (native) code and wrap it in a SWT
+	 * shell. This may have the side effect of setting data on the provided
+	 * {@link Display}.
+	 * 
+	 * @param display
+	 *            the display to parent the shell on
+	 * 
+	 * @return the splash shell or <code>null</code>
+	 * @throws InvocationTargetException
+	 * @throws IllegalAccessException
+	 * @throws IllegalArgumentException
+	 * @throws NumberFormatException
+	 * @see Display#setData(String, Object)
+	 * @since 3.4
+	 */
+	public static Shell getSplashShell(Display display)
+			throws NumberFormatException, IllegalArgumentException,
+			IllegalAccessException, InvocationTargetException {
+		Shell splashShell = (Shell) display.getData(DATA_SPLASH_SHELL);
+		if (splashShell != null)
+			return splashShell;
+
+		String splashHandle = System.getProperty(PROP_SPLASH_HANDLE);
+		if (splashHandle == null) {
+			return null;
+		}
+
+		// look for the 32 bit internal_new shell method
+		try {
+			Method method = Shell.class.getMethod(
+					"internal_new", new Class[] { Display.class, int.class }); //$NON-NLS-1$
+			// we're on a 32 bit platform so invoke it with splash
+			// handle as an int
+			splashShell = (Shell) method.invoke(null, new Object[] { display,
+					new Integer(splashHandle) });
+		} catch (NoSuchMethodException e) {
+			// look for the 64 bit internal_new shell method
+			try {
+				Method method = Shell.class
+						.getMethod(
+								"internal_new", new Class[] { Display.class, long.class }); //$NON-NLS-1$
+
+				// we're on a 64 bit platform so invoke it with a long
+				splashShell = (Shell) method.invoke(null, new Object[] {
+						display, new Long(splashHandle) });
+			} catch (NoSuchMethodException e2) {
+				// cant find either method - don't do anything.
+			}
+		}
+
+		display.setData(DATA_SPLASH_SHELL, splashShell);
+		return splashShell;
+	}
+
+	/**
+	 * Removes any splash shell data set on the provided display and disposes
+	 * the shell if necessary.
+	 * 
+	 * @param display
+	 *            the display to parent the shell on
+	 * @since 3.4
+	 */
+	public static void unsetSplashShell(Display display) {
+		Shell splashShell = (Shell) display.getData(DATA_SPLASH_SHELL);
+		if (splashShell != null) {
+			if (!splashShell.isDisposed())
+				splashShell.dispose();
+			display.setData(DATA_SPLASH_SHELL, null);
+		}
+
+	}
+
+	public void initializeContext(IEclipseContext context) {
+		e4Context = context;
+		context.set(ActionSetRegistry.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (actionSetRegistry == null) {
+					actionSetRegistry = new ActionSetRegistry();
+				}
+				return actionSetRegistry;
+			}
+		});
+		context.set(IDecoratorManager.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (decoratorManager == null) {
+					decoratorManager = new DecoratorManager();
+				}
+				return decoratorManager;
+			}
+		});
+		context.set(IEditorRegistry.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (editorRegistry == null) {
+					editorRegistry = new EditorRegistry();
+				}
+				return editorRegistry;
+			}
+		});
+		context.set(ExportWizardRegistry.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						return ExportWizardRegistry.getInstance();
+					}
+				});
+		context.set(ImportWizardRegistry.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						return ImportWizardRegistry.getInstance();
+					}
+				});
+		context.set(IIntroRegistry.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (introRegistry == null) {
+					introRegistry = new IntroRegistry();
+				}
+				return introRegistry;
+			}
+		});
+		context.set(NewWizardRegistry.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				return NewWizardRegistry.getInstance();
+			}
+		});
+		context.set(IWorkbenchOperationSupport.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						if (operationSupport == null) {
+							operationSupport = new WorkbenchOperationSupport();
+						}
+						return operationSupport;
+					}
+				});
+		context.set(IPerspectiveRegistry.class.getName(),
+				new ContextFunction() {
+					@Override
+					public Object compute(IEclipseContext context,
+							Object[] arguments) {
+						return getPerspectiveRegistry();
+					}
+				});
+		context.set(PreferenceManager.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (preferenceManager == null) {
+					preferenceManager = new WorkbenchPreferenceManager(
+							PREFERENCE_PAGE_CATEGORY_SEPARATOR);
+
+					// Get the pages from the registry
+					PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader(
+							getWorkbench());
+					registryReader.loadFromRegistry(Platform
+							.getExtensionRegistry());
+					preferenceManager.addPages(registryReader
+							.getTopLevelNodes());
+
+				}
+				return preferenceManager;
+			}
+		});
+		context.set(ISharedImages.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (sharedImages == null) {
+					sharedImages = new SharedImages();
+				}
+				return sharedImages;
+			}
+		});
+
+		context.set(IThemeRegistry.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (themeRegistry == null) {
+					themeRegistry = new ThemeRegistry();
+					ThemeRegistryReader reader = new ThemeRegistryReader();
+					reader.readThemes(Platform.getExtensionRegistry(),
+							themeRegistry);
+				}
+				return themeRegistry;
+			}
+		});
+		context.set(IViewRegistry.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (viewRegistry == null) {
+					viewRegistry = new ViewRegistry();
+				}
+				return viewRegistry;
+			}
+		});
+		context.set(IWorkingSetManager.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (workingSetManager == null) {
+					workingSetManager = new WorkingSetManager(bundleContext);
+					workingSetManager.restoreState();
+				}
+				return workingSetManager;
+			}
+		});
+		context.set(WorkingSetRegistry.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (workingSetRegistry == null) {
+					workingSetRegistry = new WorkingSetRegistry();
+					workingSetRegistry.load();
+				}
+				return workingSetRegistry;
+			}
+		});
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchWindow.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchWindow.java
new file mode 100644
index 0000000..b20df89
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchWindow.java
@@ -0,0 +1,2510 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.services.EContextService;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.workbench.ui.api.LegacySelectionService;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.e4.workbench.ui.menus.ActionSet;
+import org.eclipse.e4.workbench.ui.menus.MenuHelper;
+import org.eclipse.jface.action.ContributionManager;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.StatusLineManager;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
+import org.eclipse.jface.internal.provisional.action.IToolBarManager2;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.TextProcessor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.custom.CBanner;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.CoolBar;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.ActiveShellExpression;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPageListener;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IPersistable;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+import org.eclipse.ui.branding.IProductConstants;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.contexts.IWorkbenchContextSupport;
+import org.eclipse.ui.handlers.IHandlerActivation;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.actions.CommandAction;
+import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
+import org.eclipse.ui.internal.dnd.DragUtil;
+import org.eclipse.ui.internal.dnd.SwtUtil;
+import org.eclipse.ui.internal.expressions.WorkbenchWindowExpression;
+import org.eclipse.ui.internal.handlers.ActionCommandMappingService;
+import org.eclipse.ui.internal.handlers.ActionDelegateHandlerProxy;
+import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
+import org.eclipse.ui.internal.layout.ITrimManager;
+import org.eclipse.ui.internal.layout.IWindowTrim;
+import org.eclipse.ui.internal.layout.TrimLayout;
+import org.eclipse.ui.internal.menus.IActionSetsListener;
+import org.eclipse.ui.internal.menus.LegacyActionPersistence;
+import org.eclipse.ui.internal.menus.TrimBarManager2;
+import org.eclipse.ui.internal.menus.TrimContributionManager;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+import org.eclipse.ui.internal.misc.UIStats;
+import org.eclipse.ui.internal.presentations.DefaultActionBarPresentationFactory;
+import org.eclipse.ui.internal.progress.ProgressRegion;
+import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2;
+import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.UIExtensionTracker;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.tweaklets.WorkbenchImplementation;
+import org.eclipse.ui.menus.IMenuService;
+import org.eclipse.ui.presentations.AbstractPresentationFactory;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceScopes;
+
+/**
+ * A window within the workbench.
+ */
+public class WorkbenchWindow extends ApplicationWindow implements
+		IWorkbenchWindow {
+
+	private WorkbenchWindowAdvisor windowAdvisor;
+
+	private ActionBarAdvisor actionBarAdvisor;
+
+	private int number;
+
+	private PageList pageList = new PageList();
+
+	private PageListenerList pageListeners = new PageListenerList();
+
+	private PerspectiveListenerList perspectiveListeners = new PerspectiveListenerList();
+
+	private WWinPartService partService = new WWinPartService(this);
+
+	private WWinActionBars actionBars;
+
+	private boolean closing = false;
+
+	private boolean shellActivated = false;
+
+	private FastViewBar fastViewBar;
+
+	private PerspectiveSwitcher perspectiveSwitcher = null;
+
+	private TrimLayout defaultLayout;
+
+	ProgressRegion progressRegion = null;
+
+	// Legacy (3.2) contribution handling
+	private TrimBarManager2 trimMgr2 = null;
+
+	// 3.3 Trim Contribution handling
+	private TrimContributionManager trimContributionMgr = null;
+
+	/**
+	 * The map of services maintained by the workbench window. These services
+	 * are initialized during workbench window during the
+	 * {@link #configureShell(Shell)}.
+	 */
+	private final ServiceLocator serviceLocator;
+
+	private CBanner topBar;
+
+	// Previous shell size. Used to prevent the CBanner from triggering
+	// redundant layouts
+	// private Point lastShellSize = new Point(0, 0);
+
+	/**
+	 * The composite under which workbench pages create their controls.
+	 * 
+	 * @since 3.0
+	 */
+	private Composite pageComposite;
+
+	/**
+	 * Bit flags indication which submenus (New, Show Views, ...) this window
+	 * contains. Initially none.
+	 * 
+	 * @since 3.0
+	 */
+	private int submenus = 0x00;
+
+	/**
+	 * Object for configuring this workbench window. Lazily initialized to an
+	 * instance unique to this window.
+	 * 
+	 * @since 3.0
+	 */
+	private WorkbenchWindowConfigurer windowConfigurer = null;
+
+	/**
+	 * List of generic property listeners.
+	 * 
+	 * @since 3.3
+	 */
+	private ListenerList genericPropertyListeners = new ListenerList();
+
+	static final String TEXT_DELIMITERS = TextProcessor.getDefaultDelimiters()
+			+ "-"; //$NON-NLS-1$
+
+	// constants for shortcut bar group ids
+	static final String GRP_PAGES = "pages"; //$NON-NLS-1$
+
+	static final String GRP_PERSPECTIVES = "perspectives"; //$NON-NLS-1$
+
+	static final String GRP_FAST_VIEWS = "fastViews"; //$NON-NLS-1$
+
+	// static fields for inner classes.
+	static final int VGAP = 0;
+
+	static final int CLIENT_INSET = 3;
+
+	static final int BAR_SIZE = 23;
+
+	/**
+	 * Coolbar visibility change property.
+	 * 
+	 * @since 3.3
+	 */
+	public static final String PROP_COOLBAR_VISIBLE = "coolbarVisible"; //$NON-NLS-1$
+
+	/**
+	 * Perspective bar visibility change property.
+	 * 
+	 * @since 3.3
+	 */
+	public static final String PROP_PERSPECTIVEBAR_VISIBLE = "perspectiveBarVisible"; //$NON-NLS-1$
+
+	/**
+	 * The status line visibility change property. for internal use only.
+	 * 
+	 * @since 3.4
+	 */
+	public static final String PROP_STATUS_LINE_VISIBLE = "statusLineVisible"; //$NON-NLS-1$
+
+	/**
+	 * Constant (bit mask) indicating which the Show View submenu is probably
+	 * present somewhere in this window.
+	 * 
+	 * @see #addSubmenu
+	 * @since 3.0
+	 */
+	public static final int SHOW_VIEW_SUBMENU = 0x01;
+
+	/**
+	 * Constant (bit mask) indicating which the Open Perspective submenu is
+	 * probably present somewhere in this window.
+	 * 
+	 * @see #addSubmenu
+	 * @since 3.0
+	 */
+	public static final int OPEN_PERSPECTIVE_SUBMENU = 0x02;
+
+	/**
+	 * Constant (bit mask) indicating which the New Wizard submenu is probably
+	 * present somewhere in this window.
+	 * 
+	 * @see #addSubmenu
+	 * @since 3.0
+	 */
+	public static final int NEW_WIZARD_SUBMENU = 0x04;
+
+	/**
+	 * Remembers that this window contains the given submenu.
+	 * 
+	 * @param type
+	 *            the type of submenu, one of: {@link #NEW_WIZARD_SUBMENU
+	 *            NEW_WIZARD_SUBMENU}, {@link #OPEN_PERSPECTIVE_SUBMENU
+	 *            OPEN_PERSPECTIVE_SUBMENU}, {@link #SHOW_VIEW_SUBMENU
+	 *            SHOW_VIEW_SUBMENU}
+	 * @see #containsSubmenu
+	 * @since 3.0
+	 */
+	public void addSubmenu(int type) {
+		submenus |= type;
+	}
+
+	/**
+	 * Checks to see if this window contains the given type of submenu.
+	 * 
+	 * @param type
+	 *            the type of submenu, one of: {@link #NEW_WIZARD_SUBMENU
+	 *            NEW_WIZARD_SUBMENU}, {@link #OPEN_PERSPECTIVE_SUBMENU
+	 *            OPEN_PERSPECTIVE_SUBMENU}, {@link #SHOW_VIEW_SUBMENU
+	 *            SHOW_VIEW_SUBMENU}
+	 * @return <code>true</code> if window contains submenu, <code>false</code>
+	 *         otherwise
+	 * @see #addSubmenu
+	 * @since 3.0
+	 */
+	public boolean containsSubmenu(int type) {
+		return ((submenus & type) != 0);
+	}
+
+	/**
+	 * Constant indicating that all the actions bars should be filled.
+	 * 
+	 * @since 3.0
+	 */
+	private static final int FILL_ALL_ACTION_BARS = ActionBarAdvisor.FILL_MENU_BAR
+			| ActionBarAdvisor.FILL_COOL_BAR
+			| ActionBarAdvisor.FILL_STATUS_LINE;
+
+	/**
+	 * Creates and initializes a new workbench window.
+	 * 
+	 * @param number
+	 *            the number for the window
+	 */
+	public WorkbenchWindow(int number) {
+		super(null);
+		this.number = number;
+
+		// Make sure there is a workbench. This call will throw
+		// an exception if workbench not created yet.
+		final Workbench workbench = (Workbench) PlatformUI.getWorkbench();
+		createE4Model(workbench);
+		e4Context = e4Window.getContext();
+
+		IServiceLocatorCreator slc = (IServiceLocatorCreator) workbench
+				.getService(IServiceLocatorCreator.class);
+		this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+				workbench, null, new IDisposable() {
+					public void dispose() {
+						final Shell shell = getShell();
+						if (shell != null && !shell.isDisposed()) {
+							close();
+						}
+					}
+				});
+		serviceLocator.setContext(e4Context);
+
+		initializeDefaultServices();
+
+		// Add contribution managers that are exposed to other plugins.
+		addMenuBar();
+		addCoolBar(SWT.NONE); // style is unused
+		addStatusLine();
+
+		fireWindowOpening();
+
+		// set the shell style
+		setShellStyle(getWindowConfigurer().getShellStyle());
+
+		// Fill the action bars
+		fillActionBars(FILL_ALL_ACTION_BARS);
+		MenuHelper.loadMainMenu(e4Window.getContext(), e4Window.getMainMenu(),
+				getMenuBarManager());
+		e4ActionSets = MenuHelper.processActionSets(e4Window.getContext(),
+				e4Window.getMainMenu());
+	}
+
+	/**
+	 * @param workbench
+	 */
+	private void createE4Model(Workbench workbench) {
+		e4Window = MApplicationFactory.eINSTANCE.createWindow();
+		MApplication app = (MApplication) workbench
+				.getService(MApplication.class);
+		app.getChildren().add(e4Window);
+		e4Window.setWidth(1024);
+		e4Window.setHeight(768);
+		e4Window.setName("MyWindow"); //$NON-NLS-1$
+		initializeWindowImages(e4Window);
+		final MMenu mainMenu = MApplicationFactory.eINSTANCE.createMenu();
+		mainMenu.setId(MenuHelper.MAIN_MENU_ID);
+		e4Window.setMainMenu(mainMenu);
+	}
+
+	/**
+	 * Set the images corresponding to the workbench window
+	 */
+	private void initializeWindowImages(MWindow window) {
+		IProduct product = Platform.getProduct();
+		String images = product == null ? null : product
+				.getProperty(IProductConstants.WINDOW_IMAGES);
+		if (images == null) {
+			// backwards compatibility
+			images = product == null ? null : product
+					.getProperty(IProductConstants.WINDOW_IMAGE);
+		}
+		if (images == null)
+			return;
+		// for now just take the first image - the model currently only accepts
+		// one image
+		if (images.indexOf(',') > 0)
+			images = images.substring(0, images.indexOf(','));
+		URL iconURL = FileLocator.find(product.getDefiningBundle(), new Path(
+				images), null);
+		if (iconURL != null)
+			e4Window.setIconURI(iconURL.toExternalForm());
+	}
+
+	/**
+	 * Return the style bits for the shortcut bar.
+	 * 
+	 * @return int
+	 */
+	protected int perspectiveBarStyle() {
+		return SWT.FLAT | SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL;
+	}
+
+	private TrimDropTarget trimDropTarget;
+
+	private boolean coolBarVisible = true;
+
+	private boolean perspectiveBarVisible = true;
+
+	private boolean fastViewBarVisible = true;
+
+	private boolean statusLineVisible = true;
+
+	private IWindowTrim statusLineTrim = null;
+
+	/**
+	 * The handlers for global actions that were last submitted to the workbench
+	 * command support. This is a map of command identifiers to
+	 * <code>ActionHandler</code>. This map is never <code>null</code>, and is
+	 * never empty as long as at least one global action has been registered.
+	 */
+	private Map globalActionHandlersByCommandId = new HashMap();
+
+	/**
+	 * The list of handler submissions submitted to the workbench command
+	 * support. This list may be empty, but it is never <code>null</code>.
+	 */
+	private List handlerActivations = new ArrayList();
+
+	/**
+	 * The number of large updates that are currently going on. If this is
+	 * number is greater than zero, then UI updateActionBars is a no-op.
+	 * 
+	 * @since 3.1
+	 */
+	private int largeUpdates = 0;
+
+	private IExtensionTracker tracker;
+
+	void registerGlobalAction(IAction globalAction) {
+		String commandId = globalAction.getActionDefinitionId();
+
+		if (commandId != null) {
+			final Object value = globalActionHandlersByCommandId.get(commandId);
+			if (value instanceof ActionHandler) {
+				// This handler is about to get clobbered, so dispose it.
+				final ActionHandler handler = (ActionHandler) value;
+				handler.dispose();
+			}
+
+			if (globalAction instanceof CommandAction) {
+				final String actionId = globalAction.getId();
+				if (actionId != null) {
+					final IActionCommandMappingService mappingService = (IActionCommandMappingService) serviceLocator
+							.getService(IActionCommandMappingService.class);
+					mappingService.map(actionId, commandId);
+				}
+			} else {
+				globalActionHandlersByCommandId.put(commandId,
+						new ActionHandler(globalAction));
+			}
+		}
+
+		submitGlobalActions();
+	}
+
+	/**
+	 * <p>
+	 * Submits the action handlers for action set actions and global actions.
+	 * Global actions are given priority, so that if a global action and an
+	 * action set action both handle the same command, the global action is
+	 * given priority.
+	 * </p>
+	 * <p>
+	 * These submissions are submitted as <code>Priority.LEGACY</code>, which
+	 * means that they are the lowest priority. This means that if a higher
+	 * priority submission handles the same command under the same conditions,
+	 * that that submission will become the handler.
+	 * </p>
+	 */
+	void submitGlobalActions() {
+		final IHandlerService handlerService = (IHandlerService) serviceLocator
+				.getService(IHandlerService.class);
+
+		/*
+		 * Mash the action sets and global actions together, with global actions
+		 * taking priority.
+		 */
+		Map handlersByCommandId = new HashMap();
+		handlersByCommandId.putAll(globalActionHandlersByCommandId);
+
+		List newHandlers = new ArrayList(handlersByCommandId.size());
+
+		Iterator existingIter = handlerActivations.iterator();
+		while (existingIter.hasNext()) {
+			IHandlerActivation next = (IHandlerActivation) existingIter.next();
+
+			String cmdId = next.getCommandId();
+
+			Object handler = handlersByCommandId.get(cmdId);
+			if (handler == next.getHandler()) {
+				handlersByCommandId.remove(cmdId);
+				newHandlers.add(next);
+			} else {
+				handlerService.deactivateHandler(next);
+			}
+		}
+
+		final Shell shell = getShell();
+		if (shell != null) {
+			final Expression expression = new ActiveShellExpression(shell);
+			for (Iterator iterator = handlersByCommandId.entrySet().iterator(); iterator
+					.hasNext();) {
+				Map.Entry entry = (Map.Entry) iterator.next();
+				String commandId = (String) entry.getKey();
+				IHandler handler = (IHandler) entry.getValue();
+				newHandlers.add(handlerService.activateHandler(commandId,
+						handler, expression));
+			}
+		}
+
+		handlerActivations = newHandlers;
+	}
+
+	/**
+	 * Add a generic property listener.
+	 * 
+	 * @param listener
+	 *            the listener to add
+	 * @since 3.3
+	 */
+	public void addPropertyChangeListener(IPropertyChangeListener listener) {
+		genericPropertyListeners.add(listener);
+	}
+
+	/**
+	 * Removes a generic property listener.
+	 * 
+	 * @param listener
+	 *            the listener to remove
+	 * @since 3.3
+	 */
+	public void removePropertyChangeListener(IPropertyChangeListener listener) {
+		genericPropertyListeners.remove(listener);
+	}
+
+	/*
+	 * Adds an listener to the part service.
+	 */
+	public void addPageListener(IPageListener l) {
+		pageListeners.addPageListener(l);
+	}
+
+	/**
+	 * @see org.eclipse.ui.IPageService
+	 */
+	public void addPerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
+		perspectiveListeners.addPerspectiveListener(l);
+	}
+
+	/**
+	 * Configures this window to have a perspecive bar. Does nothing if it
+	 * already has one.
+	 */
+	protected void addPerspectiveBar(int style) {
+		Assert.isTrue(perspectiveSwitcher == null);
+		perspectiveSwitcher = new PerspectiveSwitcher(this, topBar, style);
+	}
+
+	/**
+	 * Close the window.
+	 * 
+	 * Assumes that busy cursor is active.
+	 */
+	private boolean busyClose() {
+		// Whether the window was actually closed or not
+		boolean windowClosed = false;
+
+		// Setup internal flags to indicate window is in
+		// progress of closing and no update should be done.
+		closing = true;
+
+		try {
+			// Only do the check if it is OK to close if we are not closing
+			// via the workbench as the workbench will check this itself.
+			Workbench workbench = getWorkbenchImpl();
+			int count = workbench.getWorkbenchWindowCount();
+			// also check for starting - if the first window dies on startup
+			// then we'll need to open a default window.
+			if (!workbench.isStarting()
+					&& !workbench.isClosing()
+					&& count <= 1
+					&& workbench.getWorkbenchConfigurer()
+							.getExitOnLastWindowClose()) {
+				windowClosed = workbench.close();
+			} else {
+				if (okToClose()) {
+					windowClosed = hardClose();
+				}
+			}
+		} finally {
+			if (!windowClosed) {
+				// Reset the internal flags if window was not closed.
+				closing = false;
+			}
+		}
+
+		if (windowClosed && tracker != null) {
+			tracker.close();
+		}
+
+		return windowClosed;
+	}
+
+	/**
+	 * Opens a new page. Assumes that busy cursor is active.
+	 * <p>
+	 * <b>Note:</b> Since release 2.0, a window is limited to contain at most
+	 * one page. If a page exist in the window when this method is used, then
+	 * another window is created for the new page. Callers are strongly
+	 * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
+	 * programmatically show a perspective.
+	 * </p>
+	 */
+	protected IWorkbenchPage busyOpenPage(String perspID, IAdaptable input)
+			throws WorkbenchException {
+		IWorkbenchPage newPage = null;
+
+		if (pageList.isEmpty()) {
+			newPage = ((WorkbenchImplementation) Tweaklets
+					.get(WorkbenchImplementation.KEY)).createWorkbenchPage(
+					this, perspID, input);
+			pageList.add(newPage);
+			firePageOpened(newPage);
+			setActivePage(newPage);
+		} else {
+			IWorkbenchWindow window = getWorkbench().openWorkbenchWindow(
+					perspID, input);
+			newPage = window.getActivePage();
+		}
+
+		return newPage;
+	}
+
+	/**
+	 * @see Window
+	 */
+	public int open() {
+		fireWindowCreated();
+		// getWindowAdvisor().openIntro();
+		// int result = super.open();
+		org.eclipse.e4.workbench.ui.internal.Workbench e4Workbench = (org.eclipse.e4.workbench.ui.internal.Workbench) e4Window
+				.getContext().get(
+						org.eclipse.e4.workbench.ui.internal.Workbench.class
+								.getName());
+		e4Workbench.createGUI(e4Window);
+
+		// It's time for a layout ... to insure that if TrimLayout
+		// is in play, it updates all of the trim it's responsible
+		// for. We have to do this before updating in order to get
+		// the PerspectiveBar management correct...see defect 137334
+		if (getShell().getChildren()[0] instanceof Composite) {
+			try {
+				Field field = Window.class.getDeclaredField("contents"); //$NON-NLS-1$
+				field.setAccessible(true);
+				field.set(this, getShell().getChildren()[0]);
+			} catch (SecurityException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (NoSuchFieldException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalArgumentException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME, getShell());
+		// createStatusLine(getShell());
+		getShell().layout();
+		getShell().addShellListener(getShellListener());
+		getShell().setData(this);
+		String title = getWindowConfigurer().basicGetTitle();
+		if (title != null) {
+			getShell().setText(TextProcessor.process(title, TEXT_DELIMITERS));
+		}
+
+		submitGlobalActions();
+
+		fireWindowOpened();
+		if (perspectiveSwitcher != null) {
+			perspectiveSwitcher.updatePerspectiveBar();
+			perspectiveSwitcher.updateBarParent();
+		}
+
+		return OK;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.window.Window#getShell()
+	 */
+	@Override
+	public Shell getShell() {
+		return (Shell) e4Window.getWidget();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on Window.
+	 */
+	protected boolean canHandleShellCloseEvent() {
+		if (!super.canHandleShellCloseEvent()) {
+			return false;
+		}
+		// let the advisor or other interested parties
+		// veto the user's explicit request to close the window
+		return fireWindowShellClosing();
+	}
+
+	/**
+	 * @see IWorkbenchWindow
+	 */
+	public boolean close() {
+		final boolean[] ret = new boolean[1];
+		BusyIndicator.showWhile(null, new Runnable() {
+			public void run() {
+				ret[0] = busyClose();
+			}
+		});
+		return ret[0];
+	}
+
+	protected boolean isClosing() {
+		return closing || getWorkbenchImpl().isClosing();
+	}
+
+	/**
+	 * Return whether or not the coolbar layout is locked.
+	 */
+	protected boolean isCoolBarLocked() {
+		ICoolBarManager cbm = getCoolBarManager2();
+		return cbm != null && cbm.getLockLayout();
+	}
+
+	/**
+	 * Close all of the pages.
+	 */
+	private void closeAllPages() {
+		// Deactivate active page.
+		setActivePage(null);
+
+		// Clone and deref all so that calls to getPages() returns
+		// empty list (if call by pageClosed event handlers)
+		PageList oldList = pageList;
+		pageList = new PageList();
+
+		// Close all.
+		Iterator itr = oldList.iterator();
+		while (itr.hasNext()) {
+			WorkbenchPage page = (WorkbenchPage) itr.next();
+			firePageClosed(page);
+			page.dispose();
+		}
+	}
+
+	/**
+	 * Save and close all of the pages.
+	 */
+	public void closeAllPages(boolean save) {
+		if (save) {
+			boolean ret = saveAllPages(true);
+			if (!ret) {
+				return;
+			}
+		}
+		closeAllPages();
+	}
+
+	/**
+	 * closePerspective method comment.
+	 */
+	protected boolean closePage(IWorkbenchPage in, boolean save) {
+
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets
+	 * .Shell)
+	 */
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+	}
+
+	/* package */ShellPool getDetachedWindowPool() {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.window.ApplicationWindow#createTrimWidgets(org.eclipse
+	 * .swt.widgets.Shell)
+	 */
+	protected void createTrimWidgets(Shell shell) {
+		// do nothing -- trim widgets are created in createDefaultContents
+	}
+
+	/**
+	 * Creates and remembers the client composite, under which workbench pages
+	 * create their controls.
+	 * 
+	 * @since 3.0
+	 */
+	protected Composite createPageComposite(Composite parent) {
+		pageComposite = new Composite(parent, SWT.NONE);
+		// use a StackLayout instead of a FillLayout (see bug 81460 [Workbench]
+		// (regression) Close all perspectives, open Java perspective, layout
+		// wrong)
+		pageComposite.setLayout(new StackLayout());
+		return pageComposite;
+	}
+
+	/**
+	 * Creates the contents of the workbench window, including trim controls and
+	 * the client composite. This MUST create the client composite via a call to
+	 * <code>createClientComposite</code>.
+	 * 
+	 * @since 3.0
+	 */
+	protected Control createContents(Composite parent) {
+		return pageComposite;
+	}
+
+	/**
+	 * If the perspective bar is drawn on the top right corner of the window,
+	 * then this method changes its appearance from curved to square. This
+	 * should have its own preference, but for now it piggy-backs on the
+	 * SHOW_TRADITIONAL_STYLE_TABS preference.
+	 * 
+	 * @param square
+	 *            true for a square banner and false otherwise
+	 */
+	public void setBannerCurve(boolean square) {
+	}
+
+	/**
+	 * Creates the default contents and layout of the shell.
+	 * 
+	 * @param shell
+	 *            the shell
+	 */
+	protected void createDefaultContents(final Shell shell) {
+		defaultLayout = new TrimLayout();
+		shell.setLayout(defaultLayout);
+
+		// System.err.println(defaultLayout.displayTrim());
+	}
+
+	/**
+	 * <p>
+	 * Returns a new menu manager for this workbench window. This menu manager
+	 * will just be a proxy to the new command-based menu service.
+	 * </p>
+	 * <p>
+	 * Subclasses may override this method to customize the menu manager.
+	 * </p>
+	 * 
+	 * @return a menu manager for this workbench window; never <code>null</code>
+	 *         .
+	 */
+	protected MenuManager createMenuManager() {
+		MenuManager manager = super.createMenuManager();
+		return manager;
+	}
+
+	/**
+	 * Set the perspective bar location
+	 * 
+	 * @param location
+	 *            the location to place the bar
+	 */
+	public void setPerspectiveBarLocation(String location) {
+	}
+
+	/**
+	 * Notifies interested parties (namely the advisor) that the window is about
+	 * to be opened.
+	 * 
+	 * @since 3.1
+	 */
+	private void fireWindowOpening() {
+		// let the org.eclipse.e4.ui.model.application do further configuration
+		getWindowAdvisor().preWindowOpen();
+	}
+
+	/**
+	 * Notifies interested parties (namely the advisor) that the window has been
+	 * restored from a previously saved state.
+	 * 
+	 * @throws WorkbenchException
+	 *             passed through from the advisor
+	 * @since 3.1
+	 */
+	void fireWindowRestored() throws WorkbenchException {
+		StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+			public void runWithException() throws Throwable {
+				getWindowAdvisor().postWindowRestore();
+			}
+		});
+	}
+
+	/**
+	 * Notifies interested parties (namely the advisor) that the window has been
+	 * created.
+	 * 
+	 * @since 3.1
+	 */
+	private void fireWindowCreated() {
+		getWindowAdvisor().postWindowCreate();
+	}
+
+	/**
+	 * Notifies interested parties (namely the advisor and the window listeners)
+	 * that the window has been opened.
+	 * 
+	 * @since 3.1
+	 */
+	private void fireWindowOpened() {
+		getWorkbenchImpl().fireWindowOpened(this);
+		getWindowAdvisor().postWindowOpen();
+	}
+
+	/**
+	 * Notifies interested parties (namely the advisor) that the window's shell
+	 * is closing. Allows the close to be vetoed.
+	 * 
+	 * @return <code>true</code> if the close should proceed, <code>false</code>
+	 *         if it should be canceled
+	 * @since 3.1
+	 */
+	private boolean fireWindowShellClosing() {
+		return getWindowAdvisor().preWindowShellClose();
+	}
+
+	/**
+	 * Notifies interested parties (namely the advisor and the window listeners)
+	 * that the window has been closed.
+	 * 
+	 * @since 3.1
+	 */
+	private void fireWindowClosed() {
+		// let the org.eclipse.e4.ui.model.application do further
+		// deconfiguration
+		getWindowAdvisor().postWindowClose();
+		getWorkbenchImpl().fireWindowClosed(this);
+	}
+
+	/**
+	 * Fires page activated
+	 */
+	void firePageActivated(IWorkbenchPage page) {
+		String label = null; // debugging only
+		if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
+			label = "activated " + page.getLabel(); //$NON-NLS-1$
+		}
+		try {
+			UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
+			UIListenerLogging.logPageEvent(this, page,
+					UIListenerLogging.WPE_PAGE_ACTIVATED);
+			pageListeners.firePageActivated(page);
+			partService.pageActivated(page);
+		} finally {
+			UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
+		}
+	}
+
+	/**
+	 * Fires page closed
+	 */
+	private void firePageClosed(IWorkbenchPage page) {
+		String label = null; // debugging only
+		if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
+			label = "closed " + page.getLabel(); //$NON-NLS-1$
+		}
+		try {
+			UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
+			UIListenerLogging.logPageEvent(this, page,
+					UIListenerLogging.WPE_PAGE_CLOSED);
+			pageListeners.firePageClosed(page);
+			partService.pageClosed(page);
+		} finally {
+			UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
+		}
+
+	}
+
+	/**
+	 * Fires page opened
+	 */
+	private void firePageOpened(IWorkbenchPage page) {
+		String label = null; // debugging only
+		if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
+			label = "opened " + page.getLabel(); //$NON-NLS-1$
+		}
+		try {
+			UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
+			UIListenerLogging.logPageEvent(this, page,
+					UIListenerLogging.WPE_PAGE_OPENED);
+			pageListeners.firePageOpened(page);
+			partService.pageOpened(page);
+		} finally {
+			UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
+		}
+	}
+
+	/**
+	 * Fires perspective activated
+	 */
+	void firePerspectiveActivated(IWorkbenchPage page,
+			IPerspectiveDescriptor perspective) {
+		UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+				UIListenerLogging.PLE_PERSP_ACTIVATED);
+		perspectiveListeners.firePerspectiveActivated(page, perspective);
+	}
+
+	/**
+	 * Fires perspective deactivated.
+	 * 
+	 * @since 3.2
+	 */
+	void firePerspectivePreDeactivate(IWorkbenchPage page,
+			IPerspectiveDescriptor perspective) {
+		UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+				UIListenerLogging.PLE_PERSP_PRE_DEACTIVATE);
+		perspectiveListeners.firePerspectivePreDeactivate(page, perspective);
+	}
+
+	/**
+	 * Fires perspective deactivated.
+	 * 
+	 * @since 3.1
+	 */
+	void firePerspectiveDeactivated(IWorkbenchPage page,
+			IPerspectiveDescriptor perspective) {
+		UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+				UIListenerLogging.PLE_PERSP_DEACTIVATED);
+		perspectiveListeners.firePerspectiveDeactivated(page, perspective);
+	}
+
+	/**
+	 * Fires perspective changed
+	 */
+	public void firePerspectiveChanged(IWorkbenchPage page,
+			IPerspectiveDescriptor perspective, String changeId) {
+		// Some callers call this even when there is no active perspective.
+		// Just ignore this case.
+		if (perspective != null) {
+			UIListenerLogging.logPerspectiveChangedEvent(this, page,
+					perspective, null, changeId);
+			perspectiveListeners.firePerspectiveChanged(page, perspective,
+					changeId);
+		}
+	}
+
+	/**
+	 * Fires perspective changed for an affected part
+	 */
+	public void firePerspectiveChanged(IWorkbenchPage page,
+			IPerspectiveDescriptor perspective,
+			IWorkbenchPartReference partRef, String changeId) {
+		// Some callers call this even when there is no active perspective.
+		// Just ignore this case.
+		if (perspective != null) {
+			UIListenerLogging.logPerspectiveChangedEvent(this, page,
+					perspective, partRef, changeId);
+			perspectiveListeners.firePerspectiveChanged(page, perspective,
+					partRef, changeId);
+		}
+	}
+
+	/**
+	 * Fires perspective closed
+	 */
+	void firePerspectiveClosed(IWorkbenchPage page,
+			IPerspectiveDescriptor perspective) {
+		UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+				UIListenerLogging.PLE_PERSP_CLOSED);
+		perspectiveListeners.firePerspectiveClosed(page, perspective);
+	}
+
+	/**
+	 * Fires perspective opened
+	 */
+	void firePerspectiveOpened(IWorkbenchPage page,
+			IPerspectiveDescriptor perspective) {
+		UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+				UIListenerLogging.PLE_PERSP_OPENED);
+		perspectiveListeners.firePerspectiveOpened(page, perspective);
+	}
+
+	/**
+	 * Fires perspective saved as.
+	 * 
+	 * @since 3.1
+	 */
+	void firePerspectiveSavedAs(IWorkbenchPage page,
+			IPerspectiveDescriptor oldPerspective,
+			IPerspectiveDescriptor newPerspective) {
+		UIListenerLogging.logPerspectiveSavedAs(this, page, oldPerspective,
+				newPerspective);
+		perspectiveListeners.firePerspectiveSavedAs(page, oldPerspective,
+				newPerspective);
+	}
+
+	/**
+	 * Returns the action bars for this window.
+	 */
+	public WWinActionBars getActionBars() {
+		if (actionBars == null) {
+			actionBars = new WWinActionBars(this);
+		}
+		return actionBars;
+	}
+
+	/**
+	 * Returns the active page.
+	 * 
+	 * @return the active page
+	 */
+	public IWorkbenchPage getActivePage() {
+		return pageList.getActive();
+	}
+
+	/**
+	 * Returns the active workbench page.
+	 * 
+	 * @return the active workbench page
+	 */
+	/* package */
+	WorkbenchPage getActiveWorkbenchPage() {
+		return pageList.getActive();
+	}
+
+	/**
+	 * Returns the page composite, under which the window's pages create their
+	 * controls.
+	 */
+	protected Composite getPageComposite() {
+		return pageComposite;
+	}
+
+	/**
+	 * Answer the menu manager for this window.
+	 */
+	public MenuManager getMenuManager() {
+		return getMenuBarManager();
+	}
+
+	/**
+	 * Returns the number. This corresponds to a page number in a window or a
+	 * window number in the workbench.
+	 */
+	public int getNumber() {
+		return number;
+	}
+
+	/**
+	 * Returns an array of the pages in the workbench window.
+	 * 
+	 * @return an array of pages
+	 */
+	public IWorkbenchPage[] getPages() {
+		return pageList.getPages();
+	}
+
+	/**
+	 * @see IWorkbenchWindow
+	 */
+	public IPartService getPartService() {
+		return partService;
+	}
+
+	/**
+	 * Returns the layout for the shell.
+	 * 
+	 * @return the layout for the shell
+	 */
+	protected Layout getLayout() {
+		return null;
+	}
+
+	/**
+	 * @see IWorkbenchWindow
+	 */
+	public ISelectionService getSelectionService() {
+		return (ISelectionService) e4Window.getContext().get(
+				ISelectionService.class.getName());
+	}
+
+	/**
+	 * Returns <code>true</code> when the window's shell is activated,
+	 * <code>false</code> when it's shell is deactivated
+	 * 
+	 * @return boolean <code>true</code> when shell activated,
+	 *         <code>false</code> when shell deactivated
+	 */
+	public boolean getShellActivated() {
+		return shellActivated;
+	}
+
+	/**
+	 * Returns the status line manager for this window (if it has one).
+	 * 
+	 * @return the status line manager, or <code>null</code> if this window does
+	 *         not have a status line
+	 * @see ApplicationWindow#addStatusLine
+	 */
+	public StatusLineManager getStatusLineManager() {
+		return super.getStatusLineManager();
+	}
+
+	private IWindowTrim getStatusLineTrim() {
+		if (statusLineTrim == null) {
+			statusLineTrim = new WindowTrimProxy(
+					getStatusLineManager().getControl(),
+					"org.eclipse.jface.action.StatusLineManager", //$NON-NLS-1$
+					WorkbenchMessages.TrimCommon_StatusLine_TrimName, SWT.NONE,
+					true);
+		}
+		return statusLineTrim;
+	}
+
+	/**
+	 * @see IWorkbenchWindow
+	 */
+	public IWorkbench getWorkbench() {
+		return PlatformUI.getWorkbench();
+	}
+
+	/*
+	 * The implementation of this method is copied from the 3.x
+	 * WorkbenchWindow's implementation. This is for rendering the group labels
+	 * within the 'Customize Perspective' dialog, amongst other places.
+	 */
+	public String getToolbarLabel(String actionSetId) {
+		ActionSetRegistry registry = WorkbenchPlugin.getDefault()
+				.getActionSetRegistry();
+		IActionSetDescriptor actionSet = registry.findActionSet(actionSetId);
+		if (actionSet != null) {
+			return actionSet.getLabel();
+		}
+
+		if (IWorkbenchActionConstants.TOOLBAR_FILE
+				.equalsIgnoreCase(actionSetId)) {
+			return WorkbenchMessages.WorkbenchWindow_FileToolbar;
+		}
+
+		if (IWorkbenchActionConstants.TOOLBAR_NAVIGATE
+				.equalsIgnoreCase(actionSetId)) {
+			return WorkbenchMessages.WorkbenchWindow_NavigateToolbar;
+		}
+
+		return null;
+	}
+
+	/**
+	 * Unconditionally close this window. Assumes the proper flags have been set
+	 * correctly (e.i. closing and updateDisabled)
+	 */
+	private boolean hardClose() {
+		boolean result;
+		try {
+			// Remove the handler submissions. Bug 64024.
+			final IWorkbench workbench = getWorkbench();
+			final IHandlerService handlerService = (IHandlerService) workbench
+					.getService(IHandlerService.class);
+			handlerService.deactivateHandlers(handlerActivations);
+			final Iterator activationItr = handlerActivations.iterator();
+			while (activationItr.hasNext()) {
+				final IHandlerActivation activation = (IHandlerActivation) activationItr
+						.next();
+				activation.getHandler().dispose();
+			}
+			handlerActivations.clear();
+			globalActionHandlersByCommandId.clear();
+
+			// Remove the enabled submissions. Bug 64024.
+			final IContextService contextService = (IContextService) workbench
+					.getService(IContextService.class);
+			contextService.unregisterShell(getShell());
+
+			closeAllPages();
+
+			fireWindowClosed();
+
+			// time to wipe our our populate
+			IMenuService menuService = (IMenuService) workbench
+					.getService(IMenuService.class);
+			menuService
+					.releaseContributions(((ContributionManager) getActionBars()
+							.getMenuManager()));
+			ICoolBarManager coolbar = getActionBars().getCoolBarManager();
+			if (coolbar != null) {
+				menuService
+						.releaseContributions(((ContributionManager) coolbar));
+			}
+
+			getActionBarAdvisor().dispose();
+			getWindowAdvisor().dispose();
+
+			// Null out the progress region. Bug 64024.
+			progressRegion = null;
+
+			// Remove drop targets
+			DragUtil.removeDragTarget(null, trimDropTarget);
+			DragUtil.removeDragTarget(getShell(), trimDropTarget);
+			trimDropTarget = null;
+
+			if (trimMgr2 != null) {
+				trimMgr2.dispose();
+				trimMgr2 = null;
+			}
+
+			if (trimContributionMgr != null) {
+				trimContributionMgr.dispose();
+				trimContributionMgr = null;
+			}
+		} finally {
+			result = super.close();
+
+			if (result) {
+				// explicitly dispose the shell here, our superclasses does not
+				// handle this scenario because they don't have a reference to
+				// the real shell, see bug 279731
+				Shell shell = getShell();
+				if (shell != null && !shell.isDisposed()) {
+					shell.dispose();
+				}
+			}
+
+			// Clear the action sets, fix for bug 27416.
+			// getActionPresentation().clearActionSets();
+			try {
+				// Bring down all of the services ... after the window goes away
+				serviceLocator.dispose();
+			} catch (Exception ex) {
+				WorkbenchPlugin.log(ex);
+			}
+			menuRestrictions.clear();
+		}
+		return result;
+	}
+
+	/**
+	 * @see IWorkbenchWindow
+	 */
+	public boolean isApplicationMenu(String menuID) {
+		// delegate this question to the action bar advisor
+		return getActionBarAdvisor().isApplicationMenu(menuID);
+	}
+
+	/**
+	 * Return whether or not the given id matches the id of the coolitems that
+	 * the org.eclipse.e4.ui.model.application creates.
+	 */
+	/* package */
+	boolean isWorkbenchCoolItemId(String id) {
+		return windowConfigurer.containsCoolItem(id);
+	}
+
+	/**
+	 * Locks/unlocks the CoolBar for the workbench.
+	 * 
+	 * @param lock
+	 *            whether the CoolBar should be locked or unlocked
+	 */
+	/* package */
+	void lockCoolBar(boolean lock) {
+		getCoolBarManager2().setLockLayout(lock);
+	}
+
+	/**
+	 * Makes the window visible and frontmost.
+	 */
+	void makeVisible() {
+		Shell shell = getShell();
+		if (shell != null && !shell.isDisposed()) {
+			// see bug 96700 and bug 4414 for a discussion on the use of open()
+			// here
+			shell.open();
+		}
+	}
+
+	/**
+	 * Called when this window is about to be closed.
+	 * 
+	 * Subclasses may overide to add code that returns <code>false</code> to
+	 * prevent closing under certain conditions.
+	 */
+	public boolean okToClose() {
+		// Save all of the editors.
+		if (!getWorkbenchImpl().isClosing()) {
+			if (!saveAllPages(true)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Opens a new page.
+	 * <p>
+	 * <b>Note:</b> Since release 2.0, a window is limited to contain at most
+	 * one page. If a page exist in the window when this method is used, then
+	 * another window is created for the new page. Callers are strongly
+	 * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
+	 * programmatically show a perspective.
+	 * </p>
+	 */
+	public IWorkbenchPage openPage(final String perspId, final IAdaptable input)
+			throws WorkbenchException {
+		Assert.isNotNull(perspId);
+
+		// Run op in busy cursor.
+		final Object[] result = new Object[1];
+		BusyIndicator.showWhile(null, new Runnable() {
+			public void run() {
+				try {
+					result[0] = busyOpenPage(perspId, input);
+				} catch (WorkbenchException e) {
+					result[0] = e;
+				}
+			}
+		});
+
+		if (result[0] instanceof IWorkbenchPage) {
+			return (IWorkbenchPage) result[0];
+		} else if (result[0] instanceof WorkbenchException) {
+			throw (WorkbenchException) result[0];
+		} else {
+			throw new WorkbenchException(
+					WorkbenchMessages.WorkbenchWindow_exceptionMessage);
+		}
+	}
+
+	/**
+	 * Opens a new page.
+	 * <p>
+	 * <b>Note:</b> Since release 2.0, a window is limited to contain at most
+	 * one page. If a page exist in the window when this method is used, then
+	 * another window is created for the new page. Callers are strongly
+	 * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
+	 * programmatically show a perspective.
+	 * </p>
+	 */
+	public IWorkbenchPage openPage(IAdaptable input) throws WorkbenchException {
+		String perspId = getWorkbenchImpl().getPerspectiveRegistry()
+				.getDefaultPerspective();
+		return openPage(perspId, input);
+	}
+
+	/*
+	 * Removes an listener from the part service.
+	 */
+	public void removePageListener(IPageListener l) {
+		pageListeners.removePageListener(l);
+	}
+
+	/**
+	 * @see org.eclipse.ui.IPageService
+	 */
+	public void removePerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
+		perspectiveListeners.removePerspectiveListener(l);
+	}
+
+	public IStatus restoreState(IMemento memento,
+			IPerspectiveDescriptor activeDescriptor) {
+
+		return Status.OK_STATUS;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IRunnableContext.
+	 */
+	public void run(boolean fork, boolean cancelable,
+			IRunnableWithProgress runnable) throws InvocationTargetException,
+			InterruptedException {
+		IWorkbenchContextSupport contextSupport = getWorkbench()
+				.getContextSupport();
+		final boolean keyFilterEnabled = contextSupport.isKeyFilterEnabled();
+
+		Control fastViewBarControl = getFastViewBar() == null ? null
+				: getFastViewBar().getControl();
+		boolean fastViewBarWasEnabled = fastViewBarControl == null ? false
+				: fastViewBarControl.getEnabled();
+
+		Control perspectiveBarControl = getPerspectiveBar() == null ? null
+				: getPerspectiveBar().getControl();
+		boolean perspectiveBarWasEnabled = perspectiveBarControl == null ? false
+				: perspectiveBarControl.getEnabled();
+
+		// Cache for any diabled trim controls
+		List disabledControls = null;
+
+		try {
+			if (fastViewBarControl != null && !fastViewBarControl.isDisposed()) {
+				fastViewBarControl.setEnabled(false);
+			}
+
+			if (perspectiveBarControl != null
+					&& !perspectiveBarControl.isDisposed()) {
+				perspectiveBarControl.setEnabled(false);
+			}
+
+			if (keyFilterEnabled) {
+				contextSupport.setKeyFilterEnabled(false);
+			}
+
+			// Disable all trim -except- the StatusLine
+			if (defaultLayout != null)
+				disabledControls = defaultLayout
+						.disableTrim(getStatusLineTrim());
+
+			super.run(fork, cancelable, runnable);
+		} finally {
+			if (fastViewBarControl != null && !fastViewBarControl.isDisposed()) {
+				fastViewBarControl.setEnabled(fastViewBarWasEnabled);
+			}
+
+			if (perspectiveBarControl != null
+					&& !perspectiveBarControl.isDisposed()) {
+				perspectiveBarControl.setEnabled(perspectiveBarWasEnabled);
+			}
+
+			if (keyFilterEnabled) {
+				contextSupport.setKeyFilterEnabled(true);
+			}
+
+			// Re-enable any disabled trim
+			if (defaultLayout != null && disabledControls != null)
+				defaultLayout.enableTrim(disabledControls);
+		}
+	}
+
+	/**
+	 * Save all of the pages. Returns true if the operation succeeded.
+	 */
+	private boolean saveAllPages(boolean bConfirm) {
+		boolean bRet = true;
+		Iterator itr = pageList.iterator();
+		while (bRet && itr.hasNext()) {
+			WorkbenchPage page = (WorkbenchPage) itr.next();
+			bRet = page.saveAllEditors(bConfirm);
+		}
+		return bRet;
+	}
+
+	/**
+	 * @see IPersistable
+	 */
+	public IStatus saveState(IMemento memento) {
+
+		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+				WorkbenchMessages.WorkbenchWindow_problemsSavingWindow, null);
+
+		return result;
+	}
+
+	/**
+	 * Sets the active page within the window.
+	 * 
+	 * @param in
+	 *            identifies the new active page, or <code>null</code> for no
+	 *            active page
+	 */
+	public void setActivePage(final IWorkbenchPage in) {
+		if (getActiveWorkbenchPage() == in) {
+			return;
+		}
+		pageList.setActive(in);
+		updateActionSets();
+		if (isClosing()) {
+			return;
+		}
+		firePageActivated(in);
+	}
+
+	/**
+	 * Returns whether or not children exist for the Window's toolbar control.
+	 * Overridden for coolbar support.
+	 * <p>
+	 * 
+	 * @return boolean true if children exist, false otherwise
+	 */
+	protected boolean toolBarChildrenExist() {
+		CoolBar coolBarControl = (CoolBar) getCoolBarControl();
+		return coolBarControl.getItemCount() > 0;
+	}
+
+	private Set menuRestrictions = new HashSet();
+
+	public Set getMenuRestrictions() {
+		return menuRestrictions;
+	}
+
+	void liftRestrictions() {
+
+	}
+
+	void imposeRestrictions() {
+
+	}
+
+	/**
+	 * update the action bars.
+	 */
+	public void updateActionBars() {
+
+	}
+
+	/**
+	 * <p>
+	 * Indicates the start of a large update within this window. This is used to
+	 * disable CPU-intensive, change-sensitive services that were temporarily
+	 * disabled in the midst of large changes. This method should always be
+	 * called in tandem with <code>largeUpdateEnd</code>, and the event loop
+	 * should not be allowed to spin before that method is called.
+	 * </p>
+	 * <p>
+	 * Important: always use with <code>largeUpdateEnd</code>!
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public final void largeUpdateStart() {
+		largeUpdates++;
+	}
+
+	/**
+	 * <p>
+	 * Indicates the end of a large update within this window. This is used to
+	 * re-enable services that were temporarily disabled in the midst of large
+	 * changes. This method should always be called in tandem with
+	 * <code>largeUpdateStart</code>, and the event loop should not be allowed
+	 * to spin before this method is called.
+	 * </p>
+	 * <p>
+	 * Important: always protect this call by using <code>finally</code>!
+	 * </p>
+	 * 
+	 * @since 3.1
+	 */
+	public final void largeUpdateEnd() {
+		if (--largeUpdates == 0) {
+			updateActionBars();
+		}
+	}
+
+	/**
+	 * Update the visible action sets. This method is typically called from a
+	 * page when the user changes the visible action sets within the
+	 * prespective.
+	 */
+	public void updateActionSets() {
+		WorkbenchPage page = pageList.getActive();
+		if (page == null) {
+			return;
+		}
+		final IActionSetDescriptor[] actionSets = page.getActionSets();
+		e4Context.set(ISources.ACTIVE_ACTION_SETS_NAME, actionSets);
+		final HashSet<String> set = new HashSet<String>();
+		for (int i = 0; i < actionSets.length; i++) {
+			set.add(actionSets[i].getId());
+		}
+		for (int i = 0; i < e4ActionSets.length; i++) {
+			if (set.contains(e4ActionSets[i].getId())) {
+				e4ActionSets[i].setVisible(true);
+			} else {
+				e4ActionSets[i].setVisible(false);
+			}
+		}
+		Shell shell = getShell();
+		if (shell != null) {
+			Menu bar = shell.getMenuBar();
+			if (bar != null) {
+				final MenuManager manager = (MenuManager) bar.getData();
+				if (manager != null) {
+					manager.update(true);
+				}
+			}
+		}
+	}
+
+	private ListenerList actionSetListeners = null;
+
+	private ListenerList backgroundSaveListeners = new ListenerList(
+			ListenerList.IDENTITY);
+
+	private MWindow e4Window;
+
+	private IEclipseContext e4Context;
+
+	private ActionSet[] e4ActionSets;
+
+	final void addActionSetsListener(final IActionSetsListener listener) {
+		if (actionSetListeners == null) {
+			actionSetListeners = new ListenerList();
+		}
+
+		actionSetListeners.add(listener);
+	}
+
+	final void removeActionSetsListener(final IActionSetsListener listener) {
+		if (actionSetListeners != null) {
+			actionSetListeners.remove(listener);
+			if (actionSetListeners.isEmpty()) {
+				actionSetListeners = null;
+			}
+		}
+	}
+
+	/**
+	 * Create the progress indicator for the receiver.
+	 * 
+	 * @param shell
+	 *            the parent shell
+	 */
+	void createProgressIndicator(Shell shell) {
+		if (getWindowConfigurer().getShowProgressIndicator()) {
+			progressRegion = new ProgressRegion();
+			progressRegion.createContents(shell, this);
+		}
+
+	}
+
+	class PageList {
+		// List of pages in the order they were created;
+		private List pagesInCreationOrder;
+
+		// List of pages where the top is the last activated.
+		private List pageInActivationOrder;
+
+		// The page explicitly activated
+		private Object active;
+
+		public PageList() {
+			pagesInCreationOrder = new ArrayList(4);
+			pageInActivationOrder = new ArrayList(4);
+		}
+
+		public boolean add(Object object) {
+			pagesInCreationOrder.add(object);
+			pageInActivationOrder.add(0, object);
+			// It will be moved to top only when activated.
+			return true;
+		}
+
+		public Iterator iterator() {
+			return pagesInCreationOrder.iterator();
+		}
+
+		public boolean contains(Object object) {
+			return pagesInCreationOrder.contains(object);
+		}
+
+		public boolean remove(Object object) {
+			if (active == object) {
+				active = null;
+			}
+			pageInActivationOrder.remove(object);
+			return pagesInCreationOrder.remove(object);
+		}
+
+		public boolean isEmpty() {
+			return pagesInCreationOrder.isEmpty();
+		}
+
+		public IWorkbenchPage[] getPages() {
+			int nSize = pagesInCreationOrder.size();
+			IWorkbenchPage[] retArray = new IWorkbenchPage[nSize];
+			pagesInCreationOrder.toArray(retArray);
+			return retArray;
+		}
+
+		public void setActive(Object page) {
+			if (active == page) {
+				return;
+			}
+
+			active = page;
+
+			if (page != null) {
+				pageInActivationOrder.remove(page);
+				pageInActivationOrder.add(page);
+			}
+		}
+
+		public WorkbenchPage getActive() {
+			return (WorkbenchPage) active;
+		}
+
+		public WorkbenchPage getNextActive() {
+			if (active == null) {
+				if (pageInActivationOrder.isEmpty()) {
+					return null;
+				}
+
+				return (WorkbenchPage) pageInActivationOrder
+						.get(pageInActivationOrder.size() - 1);
+			}
+
+			if (pageInActivationOrder.size() < 2) {
+				return null;
+			}
+
+			return (WorkbenchPage) pageInActivationOrder
+					.get(pageInActivationOrder.size() - 2);
+		}
+	}
+
+	/**
+	 * Returns the unique object that applications use to configure this window.
+	 * <p>
+	 * IMPORTANT This method is declared package-private to prevent regular
+	 * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
+	 * hold of the workbench window configurer that would allow them to tamper
+	 * with the workbench window. The workbench window configurer is available
+	 * only to the org.eclipse.e4.ui.model.application.
+	 * </p>
+	 */
+	/* package - DO NOT CHANGE */
+	WorkbenchWindowConfigurer getWindowConfigurer() {
+		if (windowConfigurer == null) {
+			// lazy initialize
+			windowConfigurer = new WorkbenchWindowConfigurer(this);
+		}
+		return windowConfigurer;
+	}
+
+	/**
+	 * Returns the workbench advisor. Assumes the workbench has been created
+	 * already.
+	 * <p>
+	 * IMPORTANT This method is declared private to prevent regular plug-ins
+	 * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
+	 * the workbench advisor that would allow them to tamper with the workbench.
+	 * The workbench advisor is internal to the
+	 * org.eclipse.e4.ui.model.application.
+	 * </p>
+	 */
+	private/* private - DO NOT CHANGE */
+	WorkbenchAdvisor getAdvisor() {
+		return getWorkbenchImpl().getAdvisor();
+	}
+
+	/**
+	 * Returns the window advisor, creating a new one for this window if needed.
+	 * <p>
+	 * IMPORTANT This method is declared package private to prevent regular
+	 * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
+	 * hold of the window advisor that would allow them to tamper with the
+	 * window. The window advisor is internal to the
+	 * org.eclipse.e4.ui.model.application.
+	 * </p>
+	 */
+	/* package private - DO NOT CHANGE */
+	WorkbenchWindowAdvisor getWindowAdvisor() {
+		if (windowAdvisor == null) {
+			windowAdvisor = getAdvisor().createWorkbenchWindowAdvisor(
+					getWindowConfigurer());
+			Assert.isNotNull(windowAdvisor);
+		}
+		return windowAdvisor;
+	}
+
+	/**
+	 * Returns the action bar advisor, creating a new one for this window if
+	 * needed.
+	 * <p>
+	 * IMPORTANT This method is declared private to prevent regular plug-ins
+	 * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
+	 * the action bar advisor that would allow them to tamper with the window's
+	 * action bars. The action bar advisor is internal to the
+	 * org.eclipse.e4.ui.model.application.
+	 * </p>
+	 */
+	private/* private - DO NOT CHANGE */
+	ActionBarAdvisor getActionBarAdvisor() {
+		if (actionBarAdvisor == null) {
+			actionBarAdvisor = getWindowAdvisor().createActionBarAdvisor(
+					getWindowConfigurer().getActionBarConfigurer());
+			Assert.isNotNull(actionBarAdvisor);
+		}
+		return actionBarAdvisor;
+	}
+
+	/*
+	 * Returns the IWorkbench implementation.
+	 */
+	private Workbench getWorkbenchImpl() {
+		return Workbench.getInstance();
+	}
+
+	/**
+	 * Fills the window's real action bars.
+	 * 
+	 * @param flags
+	 *            indicate which bars to fill
+	 */
+	public void fillActionBars(int flags) {
+		Workbench workbench = getWorkbenchImpl();
+		workbench.largeUpdateStart();
+		try {
+			getActionBarAdvisor().fillActionBars(flags);
+			//
+			// 3.3 start
+			// final IMenuService menuService = (IMenuService) serviceLocator
+			// .getService(IMenuService.class);
+			// menuService.populateContributionManager(
+			// (ContributionManager) getActionBars().getMenuManager(),
+			// MenuUtil.MAIN_MENU);
+			// ICoolBarManager coolbar = getActionBars().getCoolBarManager();
+			// if (coolbar != null) {
+			// menuService.populateContributionManager(
+			// (ContributionManager) coolbar, MenuUtil.MAIN_TOOLBAR);
+			// }
+			// 3.3 end
+		} finally {
+			workbench.largeUpdateEnd();
+		}
+	}
+
+	/**
+	 * Fills the window's proxy action bars.
+	 * 
+	 * @param proxyBars
+	 *            the proxy configurer
+	 * @param flags
+	 *            indicate which bars to fill
+	 */
+	public void fillActionBars(IActionBarConfigurer2 proxyBars, int flags) {
+		Assert.isNotNull(proxyBars);
+		WorkbenchWindowConfigurer.WindowActionBarConfigurer wab = (WorkbenchWindowConfigurer.WindowActionBarConfigurer) getWindowConfigurer()
+				.getActionBarConfigurer();
+		wab.setProxy(proxyBars);
+		try {
+			getActionBarAdvisor().fillActionBars(
+					flags | ActionBarAdvisor.FILL_PROXY);
+		} finally {
+			wab.setProxy(null);
+		}
+	}
+
+	/**
+	 * The <code>WorkbenchWindow</code> implementation of this method has the
+	 * same logic as <code>Window</code>'s implementation, but without the
+	 * resize check. We don't want to skip setting the bounds if the shell has
+	 * been resized since a free resize event occurs on Windows when the menubar
+	 * is set in configureShell.
+	 */
+	protected void initializeBounds() {
+		Point size = getInitialSize();
+		Point location = getInitialLocation(size);
+		getShell().setBounds(
+				getConstrainedShellBounds(new Rectangle(location.x, location.y,
+						size.x, size.y)));
+	}
+
+	/*
+	 * Unlike dialogs, the position of the workbench window is set by the user
+	 * and persisted across sessions. If the user wants to put the window
+	 * offscreen or spanning multiple monitors, let them (bug 74762)
+	 */
+	protected void constrainShellSize() {
+		// As long as the shell is visible on some monitor, don't change it.
+		Rectangle bounds = getShell().getBounds();
+		if (!SwtUtil.intersectsAnyMonitor(Display.getCurrent(), bounds)) {
+			super.constrainShellSize();
+		}
+	}
+
+	/*
+	 * Unlike dialogs, the position of the workbench window is set by the user
+	 * and persisted across sessions. If the user wants to put the window
+	 * offscreen or spanning multiple monitors, let them (bug 74762)
+	 */
+	protected Point getInitialLocation(Point size) {
+		Shell shell = getShell();
+		if (shell != null) {
+			return shell.getLocation();
+		}
+
+		return super.getInitialLocation(size);
+	}
+
+	/**
+	 * The <code>WorkbenchWindow</code> implementation of this method delegates
+	 * to the window configurer.
+	 * 
+	 * @since 3.0
+	 */
+	protected Point getInitialSize() {
+		return getWindowConfigurer().getInitialSize();
+	}
+
+	/**
+	 * @param visible
+	 *            whether the cool bar should be shown. This is only applicable
+	 *            if the window configurer also wishes either the cool bar to be
+	 *            visible.
+	 * @since 3.0
+	 */
+	public void setCoolBarVisible(boolean visible) {
+	}
+
+	/**
+	 * @return whether the cool bar should be shown. This is only applicable if
+	 *         the window configurer also wishes either the cool bar to be
+	 *         visible.
+	 * @since 3.0
+	 */
+	public boolean getCoolBarVisible() {
+		return coolBarVisible;
+	}
+
+	/**
+	 * @param visible
+	 *            whether the perspective bar should be shown. This is only
+	 *            applicable if the window configurer also wishes either the
+	 *            perspective bar to be visible.
+	 * @since 3.0
+	 */
+	public void setPerspectiveBarVisible(boolean visible) {
+	}
+
+	/**
+	 * @return whether the perspective bar should be shown. This is only
+	 *         applicable if the window configurer also wishes either the
+	 *         perspective bar to be visible.
+	 * @since 3.0
+	 */
+	public boolean getPerspectiveBarVisible() {
+		return perspectiveBarVisible;
+	}
+
+	/**
+	 * Tell the workbench window a visible state for the fastview bar. This is
+	 * only applicable if the window configurer also wishes the fast view bar to
+	 * be visible.
+	 * 
+	 * @param visible
+	 *            <code>true</code> or <code>false</code>
+	 * @since 3.2
+	 */
+	public void setFastViewBarVisible(boolean visible) {
+	}
+
+	/**
+	 * The workbench window take on the fastview bar. This is only applicable if
+	 * the window configurer also wishes the fast view bar to be visible.
+	 * 
+	 * @return <code>true</code> if the workbench window thinks the fastview bar
+	 *         should be visible.
+	 * @since 3.2
+	 */
+	public boolean getFastViewBarVisible() {
+		return fastViewBarVisible;
+	}
+
+	/**
+	 * @param visible
+	 *            whether the perspective bar should be shown. This is only
+	 *            applicable if the window configurer also wishes either the
+	 *            perspective bar to be visible.
+	 * @since 3.0
+	 */
+	public void setStatusLineVisible(boolean visible) {
+	}
+
+	/**
+	 * @return whether the perspective bar should be shown. This is only
+	 *         applicable if the window configurer also wishes either the
+	 *         perspective bar to be visible.
+	 * @since 3.0
+	 */
+	public boolean getStatusLineVisible() {
+		return statusLineVisible;
+	}
+
+	public boolean getShowFastViewBars() {
+		return getWindowConfigurer().getShowFastViewBars();
+	}
+
+	/**
+	 * Set the layout data for the contents of the window.
+	 */
+	void setLayoutDataForContents() {
+
+	}
+
+	/**
+	 * Returns the fast view bar.
+	 */
+	public FastViewBar getFastViewBar() {
+		return fastViewBar;
+	}
+
+	/**
+	 * Returns the perspective bar.
+	 * 
+	 * @return Returns the perspective bar, or <code>null</code> if it has not
+	 *         been initialized.
+	 */
+	public PerspectiveBarManager getPerspectiveBar() {
+		return perspectiveSwitcher == null ? null : perspectiveSwitcher
+				.getPerspectiveBar();
+	}
+
+	/**
+	 * Returns the action presentation for dynamic UI
+	 * 
+	 * @return action presentation
+	 */
+	public ActionPresentation getActionPresentation() {
+		return null;
+	}
+
+	/**
+	 * Return the action bar presentation used for creating toolbars. This is
+	 * for internal use only, used for consistency with the window.
+	 * 
+	 * @return the presentation used.
+	 */
+	public IActionBarPresentationFactory getActionBarPresentationFactory() {
+		// allow replacement of the actionbar presentation
+		IActionBarPresentationFactory actionBarPresentation;
+		AbstractPresentationFactory presentationFactory = getWindowConfigurer()
+				.getPresentationFactory();
+		if (presentationFactory instanceof IActionBarPresentationFactory) {
+			actionBarPresentation = ((IActionBarPresentationFactory) presentationFactory);
+		} else {
+			actionBarPresentation = new DefaultActionBarPresentationFactory();
+		}
+
+		return actionBarPresentation;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.window.ApplicationWindow#showTopSeperator()
+	 */
+	protected boolean showTopSeperator() {
+		return false;
+	}
+
+	/**
+	 * Returns a new cool bar manager for the window.
+	 * <p>
+	 * Subclasses may override this method to customize the cool bar manager.
+	 * </p>
+	 * 
+	 * @return a cool bar manager
+	 * @since 3.2
+	 */
+	protected ICoolBarManager createCoolBarManager2(int style) {
+		final ICoolBarManager2 coolBarManager = getActionBarPresentationFactory()
+				.createCoolBarManager();
+		return coolBarManager;
+	}
+
+	/**
+	 * Returns a new tool bar manager for the window.
+	 * <p>
+	 * Subclasses may override this method to customize the tool bar manager.
+	 * </p>
+	 * 
+	 * @return a tool bar manager
+	 * @since 3.2
+	 */
+	protected IToolBarManager createToolBarManager2(int style) {
+		final IToolBarManager2 toolBarManager = getActionBarPresentationFactory()
+				.createToolBarManager();
+		return toolBarManager;
+	}
+
+	/**
+	 * Delegate to the presentation factory.
+	 * 
+	 * @see org.eclipse.jface.window.ApplicationWindow#createStatusLineManager
+	 * @since 3.0
+	 */
+	protected StatusLineManager createStatusLineManager() {
+		// @issue ApplicationWindow and WorkbenchWindow should allow full
+		// IStatusLineManager
+		return new StatusLineManager() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.action.StatusLineManager#getProgressMonitor()
+			 */
+			@Override
+			public IProgressMonitor getProgressMonitor() {
+				return new NullProgressMonitor();
+			}
+		};
+	}
+
+	/**
+	 * Delegate to the presentation factory.
+	 * 
+	 * @see org.eclipse.jface.window.ApplicationWindow#createStatusLine
+	 * @since 3.0
+	 */
+	protected void createStatusLine(Shell shell) {
+		getWindowConfigurer().getPresentationFactory().createStatusLineControl(
+				getStatusLineManager(), shell);
+	}
+
+	/**
+	 * Updates the fast view bar, if present. TODO: The fast view bar should
+	 * update itself as necessary. All calls to this should be cleaned up.
+	 * 
+	 * @since 3.0
+	 */
+	public void updateFastViewBar() {
+	}
+
+	/**
+	 * @return Returns the progressRegion.
+	 */
+	public ProgressRegion getProgressRegion() {
+		return progressRegion;
+	}
+
+	/**
+	 * Adds the given control to the specified side of this window's trim.
+	 * 
+	 * @param trim
+	 *            the bar's IWindowTrim
+	 * @param side
+	 *            one of <code>SWT.LEFT</code>,<code>SWT.BOTTOM</code>, or
+	 *            <code>SWT.RIGHT</code> (only LEFT has been tested)
+	 * @since 3.0
+	 */
+	public void addToTrim(IWindowTrim trim, int side) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchWindow#getExtensionTracker()
+	 */
+	public IExtensionTracker getExtensionTracker() {
+		return (IExtensionTracker) e4Window.getContext().get(
+				IExtensionTracker.class.getName());
+	}
+
+	/**
+	 * Creates the perspective customization dialog.
+	 * 
+	 * @param persp
+	 *            perspective to customize
+	 * 
+	 * @return a new perspective customization dialog
+	 * @since 3.1
+	 */
+	public CustomizePerspectiveDialog createCustomizePerspectiveDialog(
+			Perspective persp) {
+		return new CustomizePerspectiveDialog(getWindowConfigurer(), persp);
+	}
+
+	/**
+	 * Returns the default page input for workbench pages opened in this window.
+	 * 
+	 * @return the default page input or <code>null</code> if none
+	 * @since 3.1
+	 */
+	IAdaptable getDefaultPageInput() {
+		return getWorkbenchImpl().getDefaultPageInput();
+	}
+
+	/**
+	 * Add a listener for perspective reordering.
+	 * 
+	 * @param listener
+	 */
+	public void addPerspectiveReorderListener(IReorderListener listener) {
+		if (perspectiveSwitcher != null) {
+			perspectiveSwitcher.addReorderListener(listener);
+		}
+	}
+
+	/**
+	 * Show the heap status
+	 * 
+	 * @param selection
+	 */
+	public void showHeapStatus(boolean selection) {
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchWindow#getTrimManager()
+	 */
+	public ITrimManager getTrimManager() {
+		return defaultLayout;
+	}
+
+	/**
+	 * Initializes all of the default command-based services for the workbench
+	 * window.
+	 */
+	private final void initializeDefaultServices() {
+		e4Context.declareModifiable(IServiceConstants.SELECTION);
+
+		e4Context.set(IExtensionTracker.class.getName(), new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				if (tracker == null) {
+					tracker = new UIExtensionTracker(getWorkbench()
+							.getDisplay());
+				}
+				return tracker;
+			}
+		});
+		e4Context.set(IPartService.class.getName(), getPartService());
+		e4Context.set(ISelectionService.class.getName(),
+				new LegacySelectionService(e4Context));
+		// END: e4 services
+		serviceLocator.registerService(IWorkbenchLocationService.class,
+				new WorkbenchLocationService(IServiceScopes.WINDOW_SCOPE,
+						getWorkbench(), this, null, null, null, 1));
+		// added back for legacy reasons
+		serviceLocator.registerService(IWorkbenchWindow.class, this);
+		serviceLocator.registerService(getClass(), this);
+
+		final ActionCommandMappingService mappingService = new ActionCommandMappingService();
+		serviceLocator.registerService(IActionCommandMappingService.class,
+				mappingService);
+
+		final LegacyActionPersistence actionPersistence = new LegacyActionPersistence(
+				this);
+		serviceLocator.registerService(LegacyActionPersistence.class,
+				actionPersistence);
+		actionPersistence.read();
+
+		// BEGIN: e4 registration
+		EContextService cs = (EContextService) e4Context
+				.get(EContextService.class.getName());
+		cs.activateContext("org.eclipse.ui.contexts.window"); //$NON-NLS-1$
+		cs.getActiveContextIds();
+		e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, this);
+		e4Context.set(ISources.ACTIVE_PART_NAME, new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				Object o = context.get(IServiceConstants.ACTIVE_PART);
+				if (o instanceof MPart) {
+					Object impl = ((MPart) o).getObject();
+					if (impl instanceof IWorkbenchPart) {
+						return impl;
+					}
+				}
+				return null;
+			}
+		});
+		e4Context.set(ISources.ACTIVE_SITE_NAME, new ContextFunction() {
+			@Override
+			public Object compute(IEclipseContext context, Object[] arguments) {
+				Object o = context.get(IServiceConstants.ACTIVE_PART);
+				if (o instanceof MPart) {
+					Object impl = ((MPart) o).getObject();
+					if (impl instanceof IWorkbenchPart) {
+						return ((IWorkbenchPart) impl).getSite();
+					}
+				}
+				return null;
+			}
+		});
+		// local handler service for local handlers
+		IHandlerService handlerService = new LegacyHandlerService(e4Context);
+		serviceLocator.registerService(IHandlerService.class, handlerService);
+		readActionSets();
+	}
+
+	private void readActionSets() {
+		WorkbenchWindowExpression windowExpression = new WorkbenchWindowExpression(
+				this);
+		ICommandService cs = (ICommandService) e4Context
+				.get(ICommandService.class.getName());
+		IConfigurationElement[] actionSetElements = ExtensionUtils
+				.getExtensions(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+		for (IConfigurationElement ase : actionSetElements) {
+			IConfigurationElement[] elements = ase
+					.getChildren(IWorkbenchRegistryConstants.TAG_ACTION);
+			for (IConfigurationElement configElement : elements) {
+				String id = MenuHelper.getId(configElement);
+				String cmdId = MenuHelper.getActionSetCommandId(configElement);
+				if (id == null || id.length() == 0
+						|| MenuHelper.getRetarget(configElement)) {
+					continue;
+				}
+				Command cmd = cs.getCommand(cmdId);
+				if (!cmd.isDefined()) {
+					Activator.trace(Policy.DEBUG_CMDS, "Still no command for " //$NON-NLS-1$
+							+ cmdId, null);
+					continue;
+				}
+				LegacyHandlerService.registerLegacyHandler(e4Context, id,
+						cmdId, new ActionDelegateHandlerProxy(configElement,
+								IWorkbenchRegistryConstants.ATT_CLASS, id,
+								new ParameterizedCommand(cmd, null), this,
+								null, null, null), windowExpression);
+			}
+		}
+	}
+
+	public final Object getService(final Class key) {
+		return serviceLocator.getService(key);
+	}
+
+	public final boolean hasService(final Class key) {
+		return serviceLocator.hasService(key);
+	}
+
+	/**
+	 * Toggle the visibility of the coolbar/perspective bar. This method
+	 * respects the window configurer and will only toggle visibility if the
+	 * item in question was originally declared visible by the window advisor.
+	 * 
+	 * @since 3.3
+	 */
+	public void toggleToolbarVisibility() {
+		boolean coolbarVisible = getCoolBarVisible();
+		boolean perspectivebarVisible = getPerspectiveBarVisible();
+		// only toggle the visibility of the components that
+		// were on initially
+		if (getWindowConfigurer().getShowCoolBar()) {
+			setCoolBarVisible(!coolbarVisible);
+		}
+		if (getWindowConfigurer().getShowPerspectiveBar()) {
+			setPerspectiveBarVisible(!perspectivebarVisible);
+		}
+		getShell().layout();
+	}
+
+	/* package */void addBackgroundSaveListener(IBackgroundSaveListener listener) {
+		backgroundSaveListeners.add(listener);
+	}
+
+	/* package */void fireBackgroundSaveStarted() {
+		Object[] listeners = backgroundSaveListeners.getListeners();
+		for (int i = 0; i < listeners.length; i++) {
+			IBackgroundSaveListener listener = (IBackgroundSaveListener) listeners[i];
+			listener.handleBackgroundSaveStarted();
+		}
+	}
+
+	/* package */void removeBackgroundSaveListener(
+			IBackgroundSaveListener listener) {
+		backgroundSaveListeners.remove(listener);
+	}
+
+	public MWindow getModelWindow() {
+		return e4Window;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/progress/WorkbenchSiteProgressService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/progress/WorkbenchSiteProgressService.java
new file mode 100644
index 0000000..10c6764
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/progress/WorkbenchSiteProgressService.java
@@ -0,0 +1,463 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ * Remy Chi Jian Suen (Versant Corporation) - bug 255005
+ *******************************************************************************/
+package org.eclipse.ui.internal.progress;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.part.WorkbenchPart;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.progress.WorkbenchJob;
+
+/**
+ * The WorkbenchSiteProgressService is the concrete implementation of the
+ * WorkbenchSiteProgressService used by the workbench components.
+ */
+public class WorkbenchSiteProgressService implements
+		IWorkbenchSiteProgressService, IJobBusyListener {
+	PartSite site;
+
+	private Collection busyJobs = Collections.synchronizedSet(new HashSet());
+
+	private Object busyLock = new Object();
+
+	IPropertyChangeListener[] changeListeners = new IPropertyChangeListener[0];
+
+	private Cursor waitCursor;
+
+	private int waitCursorJobCount;
+
+	private Object waitCursorLock = new Object();
+
+	private SiteUpdateJob updateJob;
+
+	/**
+	 * Flag that keeps state from calls to {@link #showBusy(boolean)}
+	 */
+	private int busyCount = 0;
+
+	public class SiteUpdateJob extends WorkbenchJob {
+		private boolean busy;
+
+		Object lock = new Object();
+
+		/**
+		 * Set whether we are updating with the wait or busy cursor.
+		 * 
+		 * @param cursorState
+		 */
+		void setBusy(boolean cursorState) {
+			synchronized (lock) {
+				busy = cursorState;
+			}
+		}
+
+		private SiteUpdateJob() {
+			super(ProgressMessages.WorkbenchSiteProgressService_CursorJob);
+		}
+
+		/**
+		 * Get the wait cursor. Initialize it if required.
+		 * 
+		 * @param display
+		 *            the display to create the cursor on.
+		 * @return the created cursor
+		 */
+		private Cursor getWaitCursor(Display display) {
+			if (waitCursor == null) {
+				waitCursor = new Cursor(display, SWT.CURSOR_APPSTARTING);
+			}
+			return waitCursor;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime
+		 * .IProgressMonitor)
+		 */
+		public IStatus runInUIThread(IProgressMonitor monitor) {
+			Control control = site.getPane().getControl();
+			if (control == null || control.isDisposed()) {
+				return Status.CANCEL_STATUS;
+			}
+			synchronized (lock) {
+				// Update cursors if we are doing that
+				Cursor cursor = null;
+				if (waitCursorJobCount != 0) {
+					// at least one job which is running has requested for wait
+					// cursor
+					cursor = getWaitCursor(control.getDisplay());
+				}
+				control.setCursor(cursor);
+				site.getPane().setBusy(busy);
+				IWorkbenchPart part = site.getPart();
+				if (part instanceof WorkbenchPart) {
+					((WorkbenchPart) part).showBusy(busy);
+				}
+			}
+			return Status.OK_STATUS;
+		}
+
+		void clearCursors() {
+			if (waitCursor != null) {
+				waitCursor.dispose();
+				waitCursor = null;
+			}
+		}
+
+	}
+
+	/**
+	 * Create a new instance of the receiver with a site of partSite
+	 * 
+	 * @param partSite
+	 *            PartSite.
+	 */
+	public WorkbenchSiteProgressService(final PartSite partSite) {
+		site = partSite;
+		updateJob = new SiteUpdateJob();
+		updateJob.setSystem(true);
+	}
+
+	/**
+	 * Dispose the resources allocated by the receiver.
+	 * 
+	 */
+	public void dispose() {
+		if (updateJob != null) {
+			updateJob.cancel();
+		}
+
+		ProgressManager.getInstance().removeListener(this);
+
+		if (waitCursor == null) {
+			return;
+		}
+		waitCursor.dispose();
+		waitCursor = null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IProgressService#busyCursorWhile(org.eclipse.
+	 * jface.operation.IRunnableWithProgress)
+	 */
+	public void busyCursorWhile(IRunnableWithProgress runnable)
+			throws InvocationTargetException, InterruptedException {
+		getWorkbenchProgressService().busyCursorWhile(runnable);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IWorkbenchSiteProgressService#schedule(org.eclipse
+	 * .core.runtime.jobs.Job, long, boolean)
+	 */
+	public void schedule(Job job, long delay, boolean useHalfBusyCursor) {
+		job.addJobChangeListener(getJobChangeListener(useHalfBusyCursor));
+		job.schedule(delay);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IWorkbenchSiteProgressService#schedule(org.eclipse
+	 * .core.runtime.jobs.Job, int)
+	 */
+	public void schedule(Job job, long delay) {
+		schedule(job, delay, false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IWorkbenchSiteProgressService#schedule(org.eclipse
+	 * .core.runtime.jobs.Job)
+	 */
+	public void schedule(Job job) {
+		schedule(job, 0L, false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IWorkbenchSiteProgressService#showBusyForFamily
+	 * (java.lang.Object)
+	 */
+	public void showBusyForFamily(Object family) {
+		ProgressManager.getInstance().addListenerToFamily(family, this);
+	}
+
+	/**
+	 * Get the job change listener for this site.
+	 * 
+	 * @param job
+	 * @param useHalfBusyCursor
+	 * @return IJobChangeListener
+	 */
+	public IJobChangeListener getJobChangeListener(
+			final boolean useHalfBusyCursor) {
+		return new JobChangeAdapter() {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.core.runtime.jobs.JobChangeAdapter#aboutToRun(org
+			 * .eclipse.core.runtime.jobs.IJobChangeEvent)
+			 */
+			public void aboutToRun(IJobChangeEvent event) {
+				if (useHalfBusyCursor) {
+					synchronized (waitCursorLock) {
+						waitCursorJobCount++;
+					}
+				}
+				incrementBusy(event.getJob());
+			}
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse
+			 * .core.runtime.jobs.IJobChangeEvent)
+			 */
+			public void done(IJobChangeEvent event) {
+				if (useHalfBusyCursor) {
+					synchronized (waitCursorLock) {
+						waitCursorJobCount--;
+					}
+				}
+
+				Job job = event.getJob();
+				decrementBusy(job);
+				job.removeJobChangeListener(this);
+			}
+		};
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.internal.progress.IJobBusyListener#decrementBusy(org.eclipse
+	 * .core.runtime.jobs.Job)
+	 */
+	public void decrementBusy(Job job) {
+		synchronized (busyLock) {
+			if (!busyJobs.contains(job)) {
+				return;
+			}
+			busyJobs.remove(job);
+		}
+		try {
+			decrementBusy();
+		} catch (Exception ex) {
+			// protecting against assertion failures
+			WorkbenchPlugin.log(ex);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.internal.progress.IJobBusyListener#incrementBusy(org.eclipse
+	 * .core.runtime.jobs.Job)
+	 */
+	public void incrementBusy(Job job) {
+		synchronized (busyLock) {
+			if (busyJobs.contains(job)) {
+				return;
+			}
+			busyJobs.add(job);
+		}
+		incrementBusy();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IWorkbenchSiteProgressService#warnOfContentChange
+	 * ()
+	 */
+	public void warnOfContentChange() {
+		// site.getPane().showHighlight();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IProgressService#showInDialog(org.eclipse.swt
+	 * .widgets.Shell, org.eclipse.core.runtime.jobs.Job)
+	 */
+	public void showInDialog(Shell shell, Job job) {
+		getWorkbenchProgressService().showInDialog(shell, job);
+	}
+
+	/**
+	 * Get the progress service for the workbnech,
+	 * 
+	 * @return IProgressService
+	 */
+	private IProgressService getWorkbenchProgressService() {
+		return site.getWorkbenchWindow().getWorkbench().getProgressService();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean,
+	 * org.eclipse.jface.operation.IRunnableWithProgress)
+	 */
+	public void run(boolean fork, boolean cancelable,
+			IRunnableWithProgress runnable) throws InvocationTargetException,
+			InterruptedException {
+		getWorkbenchProgressService().run(fork, cancelable, runnable);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IProgressService#runInUI(org.eclipse.jface.operation
+	 * .IRunnableContext, org.eclipse.jface.operation.IRunnableWithProgress,
+	 * org.eclipse.core.runtime.jobs.ISchedulingRule)
+	 */
+	public void runInUI(IRunnableContext context,
+			IRunnableWithProgress runnable, ISchedulingRule rule)
+			throws InvocationTargetException, InterruptedException {
+		getWorkbenchProgressService().runInUI(context, runnable, rule);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.progress.IProgressService#getLongOperationTime()
+	 */
+	public int getLongOperationTime() {
+		return getWorkbenchProgressService().getLongOperationTime();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IProgressService#registerIconForFamily(org.eclipse
+	 * .jface.resource.ImageDescriptor, java.lang.Object)
+	 */
+	public void registerIconForFamily(ImageDescriptor icon, Object family) {
+		getWorkbenchProgressService().registerIconForFamily(icon, family);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IProgressService#getIconFor(org.eclipse.core.
+	 * runtime.jobs.Job)
+	 */
+	public Image getIconFor(Job job) {
+		return getWorkbenchProgressService().getIconFor(job);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IWorkbenchSiteProgressService#showBusy(boolean)
+	 */
+	public void incrementBusy() {
+		synchronized (busyLock) {
+			this.busyCount++;
+			if (busyCount != 1) {
+				return;
+			}
+			updateJob.setBusy(true);
+		}
+		if (PlatformUI.isWorkbenchRunning()) {
+			// updateJob.schedule(100);
+		} else {
+			updateJob.cancel();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.progress.IWorkbenchSiteProgressService#showBusy(boolean)
+	 */
+	public void decrementBusy() {
+		synchronized (busyLock) {
+			Assert
+					.isTrue(
+							busyCount > 0,
+							"Ignoring unexpected call to IWorkbenchSiteProgressService.decrementBusy().  This might be due to an earlier call to this method."); //$NON-NLS-1$
+			this.busyCount--;
+			if (busyCount != 0) {
+				return;
+			}
+			updateJob.setBusy(false);
+		}
+		if (PlatformUI.isWorkbenchRunning()) {
+			// updateJob.schedule(100);
+		} else {
+			updateJob.cancel();
+		}
+	}
+
+	/**
+	 * This method is made public only for the tests. Clients should not be
+	 * using this method
+	 * 
+	 * @return the updateJob that updates the site
+	 */
+	public SiteUpdateJob getUpdateJob() {
+		return updateJob;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java
new file mode 100644
index 0000000..7c94906
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java
@@ -0,0 +1,682 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     James Blackburn - Bug 256316 getImageDescriptor() is not thread safe 
+ *******************************************************************************/
+package org.eclipse.ui.internal.registry;
+
+import java.io.File;
+import java.io.Serializable;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.program.Program;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorMatchingStrategy;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPluginContribution;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.internal.IWorkbenchConstants;
+import org.eclipse.ui.internal.WorkbenchImages;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.misc.ProgramImageDescriptor;
+import org.eclipse.ui.internal.tweaklets.InterceptContributions;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @see IEditorDescriptor
+ */
+public final class EditorDescriptor implements IEditorDescriptor, Serializable,
+		IPluginContribution {
+
+	/**
+	 * Generated serial version UID for this class.
+	 * 
+	 * @since 3.1
+	 */
+	private static final long serialVersionUID = 3905241225668998961L;
+
+	// @issue the following constants need not be public; see bug 47600
+	/**
+	 * Open internal constant. Value <code>0x01</code>.
+	 */
+	public static final int OPEN_INTERNAL = 0x01;
+
+	/**
+	 * Open in place constant. Value <code>0x02</code>.
+	 */
+	public static final int OPEN_INPLACE = 0x02;
+
+	/**
+	 * Open external constant. Value <code>0x04</code>.
+	 */
+	public static final int OPEN_EXTERNAL = 0x04;
+
+	private String editorName;
+
+	private String imageFilename;
+
+	private transient ImageDescriptor imageDesc;
+	private transient Object imageDescLock = new Object();
+
+	private boolean testImage = true;
+
+	private String className;
+
+	private String launcherName;
+
+	private String fileName;
+
+	private String id = Util.ZERO_LENGTH_STRING;
+
+	private boolean matchingStrategyChecked = false;
+	private IEditorMatchingStrategy matchingStrategy;
+
+	private Program program;
+
+	// The id of the plugin which contributed this editor, null for external
+	// editors
+	private String pluginIdentifier;
+
+	private int openMode = 0;
+
+	private transient IConfigurationElement configurationElement;
+
+	/**
+	 * Create a new instance of an editor descriptor. Limited to internal
+	 * framework calls.
+	 * 
+	 * @param element
+	 * @param id2
+	 */
+	public EditorDescriptor(String id2, IConfigurationElement element) {
+		setID(id2);
+		setConfigurationElement(element);
+	}
+
+	/**
+	 * Create a new instance of an editor descriptor. Limited to internal
+	 * framework calls.
+	 */
+	/* package */EditorDescriptor() {
+		super();
+	}
+
+	/**
+	 * Creates a descriptor for an external program.
+	 * 
+	 * @param filename
+	 *            the external editor full path and filename
+	 * @return the editor descriptor
+	 */
+	public static EditorDescriptor createForProgram(String filename) {
+		if (filename == null) {
+			throw new IllegalArgumentException();
+		}
+		EditorDescriptor editor = new EditorDescriptor();
+
+		editor.setFileName(filename);
+		editor.setID(filename);
+		editor.setOpenMode(OPEN_EXTERNAL);
+
+		// Isolate the program name (no directory or extension)
+		int start = filename.lastIndexOf(File.separator);
+		String name;
+		if (start != -1) {
+			name = filename.substring(start + 1);
+		} else {
+			name = filename;
+		}
+		int end = name.lastIndexOf('.');
+		if (end != -1) {
+			name = name.substring(0, end);
+		}
+		editor.setName(name);
+
+		// get the program icon without storing it in the registry
+		ImageDescriptor imageDescriptor = new ProgramImageDescriptor(filename,
+				0);
+		editor.setImageDescriptor(imageDescriptor);
+
+		return editor;
+	}
+
+	/**
+	 * Return the program called programName. Return null if it is not found.
+	 * 
+	 * @return org.eclipse.swt.program.Program
+	 */
+	private static Program findProgram(String programName) {
+
+		Program[] programs = Program.getPrograms();
+		for (int i = 0; i < programs.length; i++) {
+			if (programs[i].getName().equals(programName)) {
+				return programs[i];
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Create the editor action bar contributor for editors of this type.
+	 * 
+	 * @return the action bar contributor, or <code>null</code>
+	 */
+	public IEditorActionBarContributor createActionBarContributor() {
+		// Handle case for predefined editor descriptors, like the
+		// one for IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID, which
+		// don't have a configuration element.
+		if (configurationElement == null) {
+			return null;
+		}
+
+		// Get the contributor class name.
+		String className = configurationElement
+				.getAttribute(IWorkbenchRegistryConstants.ATT_CONTRIBUTOR_CLASS);
+		if (className == null) {
+			return null;
+		}
+
+		// Create the contributor object.
+		IEditorActionBarContributor contributor = null;
+		try {
+			contributor = (IEditorActionBarContributor) WorkbenchPlugin
+					.createExtension(configurationElement,
+							IWorkbenchRegistryConstants.ATT_CONTRIBUTOR_CLASS);
+		} catch (CoreException e) {
+			WorkbenchPlugin.log("Unable to create editor contributor: " + //$NON-NLS-1$
+					id, e.getStatus());
+		}
+		return contributor;
+	}
+
+	/**
+	 * Return the editor class name.
+	 * 
+	 * @return the class name
+	 */
+	public String getClassName() {
+		if (configurationElement == null) {
+			return className;
+		}
+		return RegistryReader.getClassValue(configurationElement,
+				IWorkbenchRegistryConstants.ATT_CLASS);
+	}
+
+	/**
+	 * Return the configuration element used to define this editor, or
+	 * <code>null</code>.
+	 * 
+	 * @return the element or null
+	 */
+	public IConfigurationElement getConfigurationElement() {
+		return configurationElement;
+	}
+
+	/**
+	 * Create an editor part based on this descriptor.
+	 * 
+	 * @return the editor part
+	 * @throws CoreException
+	 *             thrown if there is an issue creating the editor
+	 */
+	public IEditorPart createEditor() throws CoreException {
+		Object extension = WorkbenchPlugin.createExtension(
+				getConfigurationElement(),
+				IWorkbenchRegistryConstants.ATT_CLASS);
+		return ((InterceptContributions) Tweaklets
+				.get(InterceptContributions.KEY)).tweakEditor(extension);
+	}
+
+	/**
+	 * Return the file name of the command to execute for this editor.
+	 * 
+	 * @return the file name to execute
+	 */
+	public String getFileName() {
+		if (program == null) {
+			if (configurationElement == null) {
+				return fileName;
+			}
+			return configurationElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND);
+		}
+		return program.getName();
+	}
+
+	/**
+	 * Return the id for this editor.
+	 * 
+	 * @return the id
+	 */
+	public String getId() {
+		if (program == null) {
+			if (configurationElement == null) {
+				return Util.safeString(id);
+			}
+			return Util.safeString(configurationElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_ID));
+
+		}
+		return Util.safeString(program.getName());
+	}
+
+	/**
+	 * Return the image descriptor describing this editor.
+	 * 
+	 * @return the image descriptor
+	 */
+	public ImageDescriptor getImageDescriptor() {
+		ImageDescriptor tempDescriptor = null;
+
+		synchronized (imageDescLock) {
+			if (!testImage)
+				return imageDesc;
+
+			if (imageDesc == null) {
+				String imageFileName = getImageFilename();
+				String command = getFileName();
+				if (imageFileName != null && configurationElement != null)
+					tempDescriptor = AbstractUIPlugin
+							.imageDescriptorFromPlugin(configurationElement
+									.getNamespaceIdentifier(), imageFileName);
+				else if (command != null)
+					tempDescriptor = WorkbenchImages
+							.getImageDescriptorFromProgram(command, 0);
+			} else
+				tempDescriptor = imageDesc;
+
+			if (tempDescriptor == null) { // still null? return default image
+				imageDesc = WorkbenchImages
+						.getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
+				testImage = false;
+				return imageDesc;
+			}
+		}
+
+		// Verifies that the image descriptor generates an image. If not, the
+		// descriptor is
+		// replaced with the default image.
+		// We must create the image without holding any locks, since there is a
+		// potential for deadlock
+		// on Linux due to SWT's implementation of Image. See bugs 265028 and
+		// 256316 for details.
+		Image img = tempDescriptor.createImage(false);
+		if (img == null) // @issue what should be the default image?
+			tempDescriptor = WorkbenchImages
+					.getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
+		else
+			img.dispose();
+		// <----- End of must-not-lock part
+
+		// reenter synchronized block
+		synchronized (imageDescLock) {
+			// if another thread has set the image description, use it
+			if (!testImage)
+				return imageDesc;
+			// otherwise set the image description we calculated above
+			imageDesc = tempDescriptor;
+			testImage = false;
+			return imageDesc;
+		}
+	}
+
+	/**
+	 * The Image to use to repesent this editor
+	 */
+	/* package */void setImageDescriptor(ImageDescriptor desc) {
+		synchronized (imageDescLock) {
+			imageDesc = desc;
+			testImage = true;
+		}
+	}
+
+	/**
+	 * The name of the image describing this editor.
+	 * 
+	 * @return the image file name
+	 */
+	public String getImageFilename() {
+		if (configurationElement == null) {
+			return imageFilename;
+		}
+		return configurationElement
+				.getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
+	}
+
+	/**
+	 * Return the user printable label for this editor.
+	 * 
+	 * @return the label
+	 */
+	public String getLabel() {
+		if (program == null) {
+			if (configurationElement == null) {
+				return editorName;
+			}
+			return configurationElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+		}
+		return program.getName();
+	}
+
+	/**
+	 * Returns the class name of the launcher.
+	 * 
+	 * @return the launcher class name
+	 */
+	public String getLauncher() {
+		if (configurationElement == null) {
+			return launcherName;
+		}
+		return configurationElement
+				.getAttribute(IWorkbenchRegistryConstants.ATT_LAUNCHER);
+	}
+
+	/**
+	 * Return the contributing plugin id.
+	 * 
+	 * @return the contributing plugin id
+	 */
+	public String getPluginID() {
+		if (configurationElement != null) {
+			return configurationElement.getNamespace();
+		}
+		return pluginIdentifier;
+	}
+
+	/**
+	 * Get the program for the receiver if there is one.
+	 * 
+	 * @return Program
+	 */
+	public Program getProgram() {
+		return this.program;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#isInternal
+	 */
+	public boolean isInternal() {
+		return getOpenMode() == OPEN_INTERNAL;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#isOpenInPlace
+	 */
+	public boolean isOpenInPlace() {
+		return getOpenMode() == OPEN_INPLACE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#isOpenExternal
+	 */
+	public boolean isOpenExternal() {
+		return getOpenMode() == OPEN_EXTERNAL;
+	}
+
+	/**
+	 * Load the object properties from a memento.
+	 * 
+	 * @return <code>true</code> if the values are valid, <code>false</code>
+	 *         otherwise
+	 */
+	protected boolean loadValues(IMemento memento) {
+		editorName = memento.getString(IWorkbenchConstants.TAG_LABEL);
+		imageFilename = memento.getString(IWorkbenchConstants.TAG_IMAGE);
+		className = memento.getString(IWorkbenchConstants.TAG_CLASS);
+		launcherName = memento.getString(IWorkbenchConstants.TAG_LAUNCHER);
+		fileName = memento.getString(IWorkbenchConstants.TAG_FILE);
+		id = Util.safeString(memento.getString(IWorkbenchConstants.TAG_ID));
+		pluginIdentifier = memento.getString(IWorkbenchConstants.TAG_PLUGIN);
+
+		Integer openModeInt = memento
+				.getInteger(IWorkbenchConstants.TAG_OPEN_MODE);
+		if (openModeInt != null) {
+			openMode = openModeInt.intValue();
+		} else {
+			// legacy: handle the older attribute names, needed to allow reading
+			// of pre-3.0-RCP workspaces
+			boolean internal = new Boolean(memento
+					.getString(IWorkbenchConstants.TAG_INTERNAL))
+					.booleanValue();
+			boolean openInPlace = new Boolean(memento
+					.getString(IWorkbenchConstants.TAG_OPEN_IN_PLACE))
+					.booleanValue();
+			if (internal) {
+				openMode = OPEN_INTERNAL;
+			} else {
+				if (openInPlace) {
+					openMode = OPEN_INPLACE;
+				} else {
+					openMode = OPEN_EXTERNAL;
+				}
+			}
+		}
+		if (openMode != OPEN_EXTERNAL && openMode != OPEN_INTERNAL
+				&& openMode != OPEN_INPLACE) {
+			WorkbenchPlugin
+					.log("Ignoring editor descriptor with invalid openMode: " + this); //$NON-NLS-1$
+			return false;
+		}
+
+		String programName = memento
+				.getString(IWorkbenchConstants.TAG_PROGRAM_NAME);
+		if (programName != null) {
+			this.program = findProgram(programName);
+		}
+		return true;
+	}
+
+	/**
+	 * Save the object values in a IMemento
+	 */
+	protected void saveValues(IMemento memento) {
+		memento.putString(IWorkbenchConstants.TAG_LABEL, getLabel());
+		memento.putString(IWorkbenchConstants.TAG_IMAGE, getImageFilename());
+		memento.putString(IWorkbenchConstants.TAG_CLASS, getClassName());
+		memento.putString(IWorkbenchConstants.TAG_LAUNCHER, getLauncher());
+		memento.putString(IWorkbenchConstants.TAG_FILE, getFileName());
+		memento.putString(IWorkbenchConstants.TAG_ID, getId());
+		memento.putString(IWorkbenchConstants.TAG_PLUGIN, getPluginId());
+
+		memento.putInteger(IWorkbenchConstants.TAG_OPEN_MODE, getOpenMode());
+		// legacy: handle the older attribute names, needed to allow reading of
+		// workspace by pre-3.0-RCP eclipses
+		memento.putString(IWorkbenchConstants.TAG_INTERNAL, String
+				.valueOf(isInternal()));
+		memento.putString(IWorkbenchConstants.TAG_OPEN_IN_PLACE, String
+				.valueOf(isOpenInPlace()));
+
+		if (this.program != null) {
+			memento.putString(IWorkbenchConstants.TAG_PROGRAM_NAME,
+					this.program.getName());
+		}
+	}
+
+	/**
+	 * Return the open mode of this editor.
+	 * 
+	 * @return the open mode of this editor
+	 * @since 3.1
+	 */
+	private int getOpenMode() {
+		if (configurationElement == null) { // if we've been serialized, return
+			// our serialized value
+			return openMode;
+		} else if (getLauncher() != null) {
+			// open using a launcer
+			return EditorDescriptor.OPEN_EXTERNAL;
+		} else if (getFileName() != null) {
+			// open using an external editor
+			return EditorDescriptor.OPEN_EXTERNAL;
+		} else if (getPluginId() != null) {
+			// open using an internal editor
+			return EditorDescriptor.OPEN_INTERNAL;
+		} else {
+			return 0; // default for system editor
+		}
+	}
+
+	/**
+	 * Set the class name of an internal editor.
+	 */
+	/* package */void setClassName(String newClassName) {
+		className = newClassName;
+	}
+
+	/**
+	 * Set the configuration element which contributed this editor.
+	 */
+	/* package */void setConfigurationElement(
+			IConfigurationElement newConfigurationElement) {
+		configurationElement = newConfigurationElement;
+	}
+
+	/**
+	 * Set the filename of an external editor.
+	 */
+	/* package */void setFileName(String aFileName) {
+		fileName = aFileName;
+	}
+
+	/**
+	 * Set the id of the editor. For internal editors this is the id as provided
+	 * in the extension point For external editors it is path and filename of
+	 * the editor
+	 */
+	/* package */void setID(String anID) {
+		Assert.isNotNull(anID);
+		id = anID;
+	}
+
+	/**
+	 * The name of the image to use for this editor.
+	 */
+	/* package */void setImageFilename(String aFileName) {
+		imageFilename = aFileName;
+	}
+
+	/**
+	 * Sets the new launcher class name
+	 * 
+	 * @param newLauncher
+	 *            the new launcher
+	 */
+	/* package */void setLauncher(String newLauncher) {
+		launcherName = newLauncher;
+	}
+
+	/**
+	 * The label to show for this editor.
+	 */
+	/* package */void setName(String newName) {
+		editorName = newName;
+	}
+
+	/**
+	 * Sets the open mode of this editor descriptor.
+	 * 
+	 * @param mode
+	 *            the open mode
+	 * 
+	 * @issue this method is public as a temporary fix for bug 47600
+	 */
+	public void setOpenMode(int mode) {
+		openMode = mode;
+	}
+
+	/**
+	 * The id of the plugin which contributed this editor, null for external
+	 * editors.
+	 */
+	/* package */void setPluginIdentifier(String anID) {
+		pluginIdentifier = anID;
+	}
+
+	/**
+	 * Set the receivers program.
+	 * 
+	 * @param newProgram
+	 */
+	/* package */void setProgram(Program newProgram) {
+
+		this.program = newProgram;
+		if (editorName == null) {
+			setName(newProgram.getName());
+		}
+	}
+
+	/**
+	 * For debugging purposes only.
+	 */
+	public String toString() {
+		return "EditorDescriptor(id=" + getId() + ", label=" + getLabel() + ")"; //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.activities.support.IPluginContribution#getLocalId()
+	 */
+	public String getLocalId() {
+		return getId();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.activities.support.IPluginContribution#getPluginId()
+	 */
+	public String getPluginId() {
+		return getPluginID();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#getEditorManagementPolicy()
+	 */
+	public IEditorMatchingStrategy getEditorMatchingStrategy() {
+		if (matchingStrategy == null && !matchingStrategyChecked) {
+			matchingStrategyChecked = true;
+			if (program == null && configurationElement != null) {
+				if (configurationElement
+						.getAttribute(IWorkbenchRegistryConstants.ATT_MATCHING_STRATEGY) != null) {
+					try {
+						matchingStrategy = (IEditorMatchingStrategy) WorkbenchPlugin
+								.createExtension(
+										configurationElement,
+										IWorkbenchRegistryConstants.ATT_MATCHING_STRATEGY);
+					} catch (CoreException e) {
+						WorkbenchPlugin
+								.log(
+										"Error creating editor management policy for editor id " + getId(), e); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+		return matchingStrategy;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/services/ServiceLocator.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/services/ServiceLocator.java
new file mode 100644
index 0000000..9697efa
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/services/ServiceLocator.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.internal.services;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.ui.services.AbstractServiceFactory;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * @since 3.2
+ * 
+ */
+public final class ServiceLocator implements IDisposable, INestable,
+		IServiceLocator {
+	boolean activated = false;
+
+	// private AbstractServiceFactory factory;
+
+	/**
+	 * The parent for this service locator. If a service can't be found in this
+	 * locator, then the parent is asked. This value may be <code>null</code> if
+	 * there is no parent.
+	 */
+	// private IServiceLocator parent;
+
+	private boolean disposed;
+
+	private final IDisposable owner;
+
+	private IEclipseContext e4Context;
+
+	/**
+	 * Constructs a service locator with no parent.
+	 */
+	public ServiceLocator() {
+		this(null, null, null);
+	}
+
+	/**
+	 * Constructs a service locator with the given parent.
+	 * 
+	 * @param parent
+	 *            The parent for this service locator; this value may be
+	 *            <code>null</code>.
+	 * @param factory
+	 *            a local factory that can provide services at this level
+	 * @param owner
+	 */
+	public ServiceLocator(final IServiceLocator parent,
+			AbstractServiceFactory factory, IDisposable owner) {
+		// this.parent = parent;
+		// this.factory = factory;
+		this.owner = owner;
+	}
+
+	public final void activate() {
+		activated = true;
+	}
+
+	public final void deactivate() {
+		activated = false;
+	}
+
+	public final void dispose() {
+		// parent = null;
+		e4Context = null;
+		disposed = true;
+	}
+
+	public final Object getService(final Class key) {
+		if (disposed) {
+			return null;
+		}
+		return e4Context.get(key.getName());
+	}
+
+	public final boolean hasService(final Class key) {
+		if (disposed) {
+			return false;
+		}
+		return e4Context.containsKey(key.getName());
+	}
+
+	/**
+	 * Registers a service with this locator. If there is an existing service
+	 * matching the same <code>api</code> and it implements {@link IDisposable},
+	 * it will be disposed.
+	 * 
+	 * @param api
+	 *            This is the interface that the service implements. Must not be
+	 *            <code>null</code>.
+	 * @param service
+	 *            The service to register. This must be some implementation of
+	 *            <code>api</code>. This value must not be <code>null</code>.
+	 */
+	public final void registerService(final Class api, final Object service) {
+		if (api == null) {
+			throw new NullPointerException("The service key cannot be null"); //$NON-NLS-1$
+		}
+
+		if (!api.isInstance(service)) {
+			throw new IllegalArgumentException(
+					"The service does not implement the given interface"); //$NON-NLS-1$
+		}
+		e4Context.set(api.getName(), service);
+	}
+
+	/**
+	 * @return
+	 */
+	public boolean isDisposed() {
+		return disposed;
+	}
+
+	/**
+	 * Some services that were contributed to this locator are no longer
+	 * available (because the plug-in containing the AbstractServiceFactory is
+	 * no longer available). Notify the owner of the locator about this.
+	 */
+	public void unregisterServices(String[] serviceNames) {
+		if (owner != null) {
+			owner.dispose();
+		}
+	}
+
+	public void setContext(IEclipseContext context) {
+		e4Context = context;
+	}
+
+	public IEclipseContext getContext() {
+		return e4Context;
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java
new file mode 100644
index 0000000..cb95109
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java
@@ -0,0 +1,1311 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.part;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.util.Tracing;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.dialogs.IPageChangeProvider;
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.misc.Policy;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * A multi-page editor is an editor with multiple pages, each of which may
+ * contain an editor or an arbitrary SWT control.
+ * <p>
+ * Subclasses must implement the following methods:
+ * <ul>
+ * <li><code>createPages</code> - to create the required pages by calling one of
+ * the <code>addPage</code> methods</li>
+ * <li><code>IEditorPart.doSave</code> - to save contents of editor</li>
+ * <li><code>IEditorPart.doSaveAs</code> - to save contents of editor</li>
+ * <li><code>IEditorPart.isSaveAsAllowed</code> - to enable Save As</li>
+ * <li><code>IEditorPart.gotoMarker</code> - to scroll to a marker</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Multi-page editors have a single action bar contributor, which manages
+ * contributions for all the pages. The contributor must be a subclass of
+ * <code>MultiPageEditorActionBarContributor</code>. Note that since any nested
+ * editors are created directly in code by callers of
+ * <code>addPage(IEditorPart,IEditorInput)</code>, nested editors do not have
+ * their own contributors.
+ * </p>
+ * <p>
+ * As of 3.5 multi-page editors will post PageChangedEvents at the end of
+ * {@link #pageChange(int)}. Subclasses may override {@link #getSelectedPage()}
+ * to return a page appropriate to their multi-page editor. IPartListener2
+ * listeners registered with the IPartService can implement IPageChangedListener
+ * to be notified about all page change events within the workbench page or
+ * workbench window.
+ * </p>
+ * 
+ * @see org.eclipse.ui.part.MultiPageEditorActionBarContributor
+ * @see org.eclipse.jface.dialogs.IPageChangeProvider
+ * @see org.eclipse.jface.dialogs.IPageChangedListener
+ * @see org.eclipse.ui.IPartService
+ */
+public abstract class MultiPageEditorPart extends EditorPart implements
+		IPageChangeProvider {
+
+	private static final String COMMAND_NEXT_SUB_TAB = "org.eclipse.ui.navigate.nextSubTab"; //$NON-NLS-1$
+	private static final String COMMAND_PREVIOUS_SUB_TAB = "org.eclipse.ui.navigate.previousSubTab"; //$NON-NLS-1$
+
+	/**
+	 * Subclasses that override {@link #createPageContainer(Composite)} can use
+	 * this constant to get a site for the container that can be active while
+	 * the current page is deactivated.
+	 * 
+	 * @since 3.4
+	 * @see #activateSite()
+	 * @see #deactivateSite(boolean, boolean)
+	 * @see #getPageSite(int)
+	 */
+	protected static final int PAGE_CONTAINER_SITE = 65535;
+
+	/**
+	 * Private tracing output.
+	 */
+	private static final String TRACING_COMPONENT = "MPE"; //$NON-NLS-1$
+
+	/**
+	 * The active service locator. This value may be <code>null</code> if there
+	 * is no selected page, or if the selected page is a control with no site.
+	 */
+	private INestable activeServiceLocator;
+
+	/**
+	 * The container widget.
+	 */
+	private CTabFolder container;
+
+	/**
+	 * List of nested editors. Element type: IEditorPart. Need to hang onto them
+	 * here, in addition to using get/setData on the items, because dispose()
+	 * needs to access them, but widgetry has already been disposed at that
+	 * point.
+	 */
+	private ArrayList nestedEditors = new ArrayList(3);
+
+	private List pageSites = new ArrayList(3);
+
+	private IServiceLocator pageContainerSite;
+
+	private ListenerList pageChangeListeners = new ListenerList(
+			ListenerList.IDENTITY);
+
+	/**
+	 * Creates an empty multi-page editor with no pages.
+	 */
+	protected MultiPageEditorPart() {
+		super();
+	}
+
+	/**
+	 * Creates and adds a new page containing the given control to this
+	 * multi-page editor. The control may be <code>null</code>, allowing it to
+	 * be created and set later using <code>setControl</code>.
+	 * 
+	 * @param control
+	 *            the control, or <code>null</code>
+	 * @return the index of the new page
+	 * 
+	 * @see MultiPageEditorPart#setControl(int, Control)
+	 */
+	public int addPage(Control control) {
+		int index = getPageCount();
+		addPage(index, control);
+		return index;
+	}
+
+	/**
+	 * Creates and adds a new page containing the given control to this
+	 * multi-page editor. The page is added at the given index. The control may
+	 * be <code>null</code>, allowing it to be created and set later using
+	 * <code>setControl</code>.
+	 * 
+	 * @param index
+	 *            the index at which to add the page (0-based)
+	 * @param control
+	 *            the control, or <code>null</code>
+	 * 
+	 * @see MultiPageEditorPart#setControl(int, Control)
+	 */
+	public void addPage(int index, Control control) {
+		createItem(index, control);
+	}
+
+	/**
+	 * Creates and adds a new page containing the given editor to this
+	 * multi-page editor. This also hooks a property change listener on the
+	 * nested editor.
+	 * 
+	 * @param editor
+	 *            the nested editor
+	 * @param input
+	 *            the input for the nested editor
+	 * @return the index of the new page
+	 * @exception PartInitException
+	 *                if a new page could not be created
+	 * 
+	 * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
+	 *      property change events from the nested editor
+	 */
+	public int addPage(IEditorPart editor, IEditorInput input)
+			throws PartInitException {
+		int index = getPageCount();
+		addPage(index, editor, input);
+		return index;
+	}
+
+	/**
+	 * Creates and adds a new page containing the given editor to this
+	 * multi-page editor. The page is added at the given index. This also hooks
+	 * a property change listener on the nested editor.
+	 * 
+	 * @param index
+	 *            the index at which to add the page (0-based)
+	 * @param editor
+	 *            the nested editor
+	 * @param input
+	 *            the input for the nested editor
+	 * @exception PartInitException
+	 *                if a new page could not be created
+	 * 
+	 * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
+	 *      property change events from the nested editor
+	 */
+	public void addPage(int index, IEditorPart editor, IEditorInput input)
+			throws PartInitException {
+		IEditorSite site = createSite(editor);
+		// call init first so that if an exception is thrown, we have created no
+		// new widgets
+		editor.init(site, input);
+		Composite parent2 = new Composite(getContainer(),
+				getOrientation(editor));
+		parent2.setLayout(new FillLayout());
+		editor.createPartControl(parent2);
+		editor.addPropertyListener(new IPropertyListener() {
+			public void propertyChanged(Object source, int propertyId) {
+				MultiPageEditorPart.this.handlePropertyChange(propertyId);
+			}
+		});
+		// create item for page only after createPartControl has succeeded
+		Item item = createItem(index, parent2);
+		// remember the editor, as both data on the item, and in the list of
+		// editors (see field comment)
+		item.setData(editor);
+		nestedEditors.add(editor);
+	}
+
+	/**
+	 * Get the orientation of the editor.
+	 * 
+	 * @param editor
+	 * @return int the orientation flag
+	 * @see SWT#RIGHT_TO_LEFT
+	 * @see SWT#LEFT_TO_RIGHT
+	 * @see SWT#NONE
+	 */
+	private int getOrientation(IEditorPart editor) {
+		if (editor instanceof IWorkbenchPartOrientation) {
+			return ((IWorkbenchPartOrientation) editor).getOrientation();
+		}
+		return getOrientation();
+	}
+
+	/**
+	 * Creates an empty container. Creates a CTabFolder with no style bits set,
+	 * and hooks a selection listener which calls <code>pageChange()</code>
+	 * whenever the selected tab changes.
+	 * 
+	 * @param parent
+	 *            The composite in which the container tab folder should be
+	 *            created; must not be <code>null</code>.
+	 * @return a new container
+	 */
+	private CTabFolder createContainer(Composite parent) {
+		// use SWT.FLAT style so that an extra 1 pixel border is not reserved
+		// inside the folder
+		parent.setLayout(new FillLayout());
+		final CTabFolder newContainer = new CTabFolder(parent, SWT.BOTTOM
+				| SWT.FLAT);
+		newContainer.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				int newPageIndex = newContainer.indexOf((CTabItem) e.item);
+				pageChange(newPageIndex);
+			}
+		});
+		newContainer.addTraverseListener(new TraverseListener() {
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=199499 :
+			// Switching tabs by Ctrl+PageUp/PageDown must not be caught on the
+			// inner tab set
+			public void keyTraversed(TraverseEvent e) {
+				switch (e.detail) {
+				case SWT.TRAVERSE_PAGE_NEXT:
+				case SWT.TRAVERSE_PAGE_PREVIOUS:
+					int detail = e.detail;
+					e.doit = true;
+					e.detail = SWT.TRAVERSE_NONE;
+					Control control = newContainer.getParent();
+					do {
+						if (control.traverse(detail))
+							return;
+						if (control.getListeners(SWT.Traverse).length != 0)
+							return;
+						if (control instanceof Shell)
+							return;
+						control = control.getParent();
+					} while (control != null);
+				}
+			}
+		});
+		return newContainer;
+	}
+
+	/**
+	 * Creates a tab item at the given index and places the given control in the
+	 * new item. The item is a CTabItem with no style bits set.
+	 * 
+	 * @param index
+	 *            the index at which to add the control
+	 * @param control
+	 *            is the control to be placed in an item
+	 * @return a new item
+	 */
+	private CTabItem createItem(int index, Control control) {
+		CTabItem item = new CTabItem(getTabFolder(), SWT.NONE, index);
+		item.setControl(control);
+		return item;
+	}
+
+	/**
+	 * Creates the pages of this multi-page editor.
+	 * <p>
+	 * Subclasses must implement this method.
+	 * </p>
+	 */
+	protected abstract void createPages();
+
+	/**
+	 * The <code>MultiPageEditor</code> implementation of this
+	 * <code>IWorkbenchPart</code> method creates the control for the multi-page
+	 * editor by calling <code>createContainer</code>, then
+	 * <code>createPages</code>. Subclasses should implement
+	 * <code>createPages</code> rather than overriding this method.
+	 * 
+	 * @param parent
+	 *            The parent in which the editor should be created; must not be
+	 *            <code>null</code>.
+	 */
+	public final void createPartControl(Composite parent) {
+		Composite pageContainer = createPageContainer(parent);
+		this.container = createContainer(pageContainer);
+		createPages();
+		// set the active page (page 0 by default), unless it has already been
+		// done
+		if (getActivePage() == -1) {
+			setActivePage(0);
+			IEditorPart part = getEditor(0);
+			if (part != null) {
+				final IServiceLocator serviceLocator = part.getEditorSite();
+				if (serviceLocator instanceof INestable) {
+					activeServiceLocator = (INestable) serviceLocator;
+					activeServiceLocator.activate();
+				}
+			}
+		}
+		initializePageSwitching();
+		initializeSubTabSwitching();
+	}
+
+	/**
+	 * Initialize the MultiPageEditorPart to use the page switching command.
+	 * Clients can override this method with an empty body if they wish to
+	 * opt-out.
+	 * 
+	 * @since 3.4
+	 */
+	protected void initializePageSwitching() {
+		new PageSwitcher(this) {
+			public Object[] getPages() {
+				int pageCount = getPageCount();
+				Object[] result = new Object[pageCount];
+				for (int i = 0; i < pageCount; i++) {
+					result[i] = new Integer(i);
+				}
+				return result;
+			}
+
+			public String getName(Object page) {
+				return getPageText(((Integer) page).intValue());
+			}
+
+			public ImageDescriptor getImageDescriptor(Object page) {
+				Image image = getPageImage(((Integer) page).intValue());
+				if (image == null)
+					return null;
+
+				return ImageDescriptor.createFromImage(image);
+			}
+
+			public void activatePage(Object page) {
+				setActivePage(((Integer) page).intValue());
+			}
+
+			public int getCurrentPageIndex() {
+				return getActivePage();
+			}
+		};
+	}
+
+	/**
+	 * Initialize the MultiPageEditorPart to use the sub-tab switching commands.
+	 * 
+	 * @since 3.5
+	 */
+	private void initializeSubTabSwitching() {
+		IHandlerService service = (IHandlerService) getSite().getService(
+				IHandlerService.class);
+		service.activateHandler(COMMAND_NEXT_SUB_TAB, new AbstractHandler() {
+			/**
+			 * {@inheritDoc}
+			 * 
+			 * @throws ExecutionException
+			 *             if an exception occurred during execution
+			 */
+			public Object execute(ExecutionEvent event)
+					throws ExecutionException {
+				int n = getPageCount();
+				if (n == 0)
+					return null;
+
+				int i = getActivePage() + 1;
+				if (i >= n)
+					i = 0;
+				setActivePage(i);
+				return null;
+			}
+		});
+
+		service.activateHandler(COMMAND_PREVIOUS_SUB_TAB,
+				new AbstractHandler() {
+					/**
+					 * {@inheritDoc}
+					 * 
+					 * @throws ExecutionException
+					 *             if an exception occurred during execution
+					 */
+					public Object execute(ExecutionEvent event)
+							throws ExecutionException {
+						int n = getPageCount();
+						if (n == 0)
+							return null;
+
+						int i = getActivePage() - 1;
+						if (i < 0)
+							i = n - 1;
+						setActivePage(i);
+						return null;
+					}
+				});
+	}
+
+	/**
+	 * Creates the parent control for the container returned by
+	 * {@link #getContainer() }.
+	 * 
+	 * <p>
+	 * Subclasses may extend and must call super implementation first.
+	 * </p>
+	 * 
+	 * @param parent
+	 *            the parent for all of the editors contents.
+	 * @return the parent for this editor's container. Must not be
+	 *         <code>null</code>.
+	 * 
+	 * @since 3.2
+	 */
+	protected Composite createPageContainer(Composite parent) {
+		return parent;
+	}
+
+	/**
+	 * Creates the site for the given nested editor. The
+	 * <code>MultiPageEditorPart</code> implementation of this method creates an
+	 * instance of <code>MultiPageEditorSite</code>. Subclasses may reimplement
+	 * to create more specialized sites.
+	 * 
+	 * @param editor
+	 *            the nested editor
+	 * @return the editor site
+	 */
+	protected IEditorSite createSite(IEditorPart editor) {
+		return new MultiPageEditorSite(this, editor);
+	}
+
+	/**
+	 * The <code>MultiPageEditorPart</code> implementation of this
+	 * <code>IWorkbenchPart</code> method disposes all nested editors.
+	 * Subclasses may extend.
+	 */
+	public void dispose() {
+		pageChangeListeners.clear();
+		for (int i = 0; i < nestedEditors.size(); ++i) {
+			IEditorPart editor = (IEditorPart) nestedEditors.get(i);
+			disposePart(editor);
+		}
+		nestedEditors.clear();
+		if (pageContainerSite instanceof IDisposable) {
+			((IDisposable) pageContainerSite).dispose();
+			pageContainerSite = null;
+		}
+		for (int i = 0; i < pageSites.size(); i++) {
+			IServiceLocator sl = (IServiceLocator) pageSites.get(i);
+			if (sl instanceof IDisposable) {
+				((IDisposable) sl).dispose();
+			}
+		}
+		pageSites.clear();
+		super.dispose();
+	}
+
+	/**
+	 * Returns the active nested editor if there is one.
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @nooverride
+	 * @return the active nested editor, or <code>null</code> if none
+	 */
+	protected IEditorPart getActiveEditor() {
+		int index = getActivePage();
+		if (index != -1) {
+			return getEditor(index);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the index of the currently active page, or -1 if there is no
+	 * active page.
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @nooverride
+	 * 
+	 * @return the index of the active page, or -1 if there is no active page
+	 * @since 3.5
+	 */
+	public int getActivePage() {
+		CTabFolder tabFolder = getTabFolder();
+		if (tabFolder != null && !tabFolder.isDisposed()) {
+			return tabFolder.getSelectionIndex();
+		}
+		return -1;
+	}
+
+	/**
+	 * Returns the composite control containing this multi-page editor's pages.
+	 * This should be used as the parent when creating controls for the
+	 * individual pages. That is, when calling <code>addPage(Control)</code>,
+	 * the passed control should be a child of this container.
+	 * <p>
+	 * Warning: Clients should not assume that the container is any particular
+	 * subclass of Composite. The actual class used may change in order to
+	 * improve the look and feel of multi-page editors. Any code making
+	 * assumptions on the particular subclass would thus be broken.
+	 * </p>
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @return the composite, or <code>null</code> if
+	 *         <code>createPartControl</code> has not been called yet
+	 */
+	protected Composite getContainer() {
+		return container;
+	}
+
+	/**
+	 * Returns the control for the given page index, or <code>null</code> if no
+	 * control has been set for the page. The page index must be valid.
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the control for the specified page, or <code>null</code> if none
+	 *         has been set
+	 */
+	protected Control getControl(int pageIndex) {
+		return getItem(pageIndex).getControl();
+	}
+
+	/**
+	 * Returns the editor for the given page index. The page index must be
+	 * valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the editor for the specified page, or <code>null</code> if the
+	 *         specified page was not created with
+	 *         <code>addPage(IEditorPart,IEditorInput)</code>
+	 */
+	protected IEditorPart getEditor(int pageIndex) {
+		Item item = getItem(pageIndex);
+		if (item != null) {
+			Object data = item.getData();
+			if (data instanceof IEditorPart) {
+				return (IEditorPart) data;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the service locator for the given page index. This method can be
+	 * used to create service locators for pages that are just controls. The
+	 * page index must be valid.
+	 * <p>
+	 * This will return the editor site service locator for an editor, and
+	 * create one for a page that is just a control.
+	 * </p>
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the editor for the specified page, or <code>null</code> if the
+	 *         specified page was not created with
+	 *         <code>addPage(IEditorPart,IEditorInput)</code>
+	 * @since 3.4
+	 */
+	protected final IServiceLocator getPageSite(int pageIndex) {
+		if (pageIndex == PAGE_CONTAINER_SITE) {
+			return getPageContainerSite();
+		}
+
+		Item item = getItem(pageIndex);
+		if (item != null) {
+			Object data = item.getData();
+			if (data instanceof IEditorPart) {
+				return ((IEditorPart) data).getSite();
+			} else if (data instanceof IServiceLocator) {
+				return (IServiceLocator) data;
+			} else if (data == null) {
+				IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite()
+						.getService(IServiceLocatorCreator.class);
+				IServiceLocator sl = slc.createServiceLocator(getSite(), null,
+						new IDisposable() {
+							public void dispose() {
+								final Control control = ((PartSite) getSite())
+										.getPane().getControl();
+								if (control != null && !control.isDisposed()) {
+									((PartSite) getSite()).getPane().doHide();
+								}
+							}
+						});
+				IEclipseContext e4Context = EclipseContextFactory.create(
+						((EditorSite) getSite()).getContext(),
+						UISchedulerStrategy.getInstance());
+				((ServiceLocator) sl).setContext(e4Context);
+				item.setData(sl);
+				pageSites.add(sl);
+				return sl;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @return A site that can be used with a header.
+	 * @since 3.4
+	 * @see #createPageContainer(Composite)
+	 * @see #PAGE_CONTAINER_SITE
+	 * @see #getPageSite(int)
+	 */
+	private IServiceLocator getPageContainerSite() {
+		if (pageContainerSite == null) {
+			IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite()
+					.getService(IServiceLocatorCreator.class);
+			pageContainerSite = slc.createServiceLocator(getSite(), null,
+					new IDisposable() {
+						public void dispose() {
+							final Control control = ((PartSite) getSite())
+									.getPane().getControl();
+							if (control != null && !control.isDisposed()) {
+								((PartSite) getSite()).getPane().doHide();
+							}
+						}
+					});
+			IEclipseContext e4Context = EclipseContextFactory.create(
+					((EditorSite) getSite()).getContext(), UISchedulerStrategy
+							.getInstance());
+			((ServiceLocator) pageContainerSite).setContext(e4Context);
+		}
+		return pageContainerSite;
+	}
+
+	/**
+	 * Returns the tab item for the given page index (page index is 0-based).
+	 * The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the tab item for the given page index
+	 */
+	private CTabItem getItem(int pageIndex) {
+		return getTabFolder().getItem(pageIndex);
+	}
+
+	/**
+	 * Returns the number of pages in this multi-page editor.
+	 * 
+	 * @return the number of pages
+	 */
+	protected int getPageCount() {
+		CTabFolder folder = getTabFolder();
+		// May not have been created yet, or may have been disposed.
+		if (folder != null && !folder.isDisposed()) {
+			return folder.getItemCount();
+		}
+		return 0;
+	}
+
+	/**
+	 * Returns the image for the page with the given index, or <code>null</code>
+	 * if no image has been set for the page. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the image, or <code>null</code> if none
+	 */
+	protected Image getPageImage(int pageIndex) {
+		return getItem(pageIndex).getImage();
+	}
+
+	/**
+	 * Returns the text label for the page with the given index. Returns the
+	 * empty string if no text label has been set for the page. The page index
+	 * must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the text label for the page
+	 */
+	protected String getPageText(int pageIndex) {
+		return getItem(pageIndex).getText();
+	}
+
+	/**
+	 * Returns the tab folder containing this multi-page editor's pages.
+	 * 
+	 * @return the tab folder, or <code>null</code> if
+	 *         <code>createPartControl</code> has not been called yet
+	 */
+	private CTabFolder getTabFolder() {
+		return container;
+	}
+
+	/**
+	 * Handles a property change notification from a nested editor. The default
+	 * implementation simply forwards the change to listeners on this multi-page
+	 * editor by calling <code>firePropertyChange</code> with the same property
+	 * id. For example, if the dirty state of a nested editor changes (property
+	 * id <code>IEditorPart.PROP_DIRTY</code>), this method handles it by firing
+	 * a property change event for <code>IEditorPart.PROP_DIRTY</code> to
+	 * property listeners on this multi-page editor.
+	 * <p>
+	 * Subclasses may extend or reimplement this method.
+	 * </p>
+	 * 
+	 * @param propertyId
+	 *            the id of the property that changed
+	 */
+	protected void handlePropertyChange(int propertyId) {
+		firePropertyChange(propertyId);
+	}
+
+	/**
+	 * The <code>MultiPageEditorPart</code> implementation of this
+	 * <code>IEditorPart</code> method sets its site to the given site, its
+	 * input to the given input, and the site's selection provider to a
+	 * <code>MultiPageSelectionProvider</code>. Subclasses may extend this
+	 * method.
+	 * 
+	 * @param site
+	 *            The site for which this part is being created; must not be
+	 *            <code>null</code>.
+	 * @param input
+	 *            The input on which this editor should be created; must not be
+	 *            <code>null</code>.
+	 * @throws PartInitException
+	 *             If the initialization of the part fails -- currently never.
+	 */
+	public void init(IEditorSite site, IEditorInput input)
+			throws PartInitException {
+		setSite(site);
+		setInput(input);
+		site.setSelectionProvider(new MultiPageSelectionProvider(this));
+	}
+
+	/**
+	 * The <code>MultiPageEditorPart</code> implementation of this
+	 * <code>IEditorPart</code> method returns whether the contents of any of
+	 * this multi-page editor's nested editors have changed since the last save.
+	 * Pages created with <code>addPage(Control)</code> are ignored.
+	 * <p>
+	 * Subclasses may extend or reimplement this method.
+	 * </p>
+	 * 
+	 * @return <code>true</code> if any of the nested editors are dirty;
+	 *         <code>false</code> otherwise.
+	 */
+	public boolean isDirty() {
+		// use nestedEditors to avoid SWT requests; see bug 12996
+		for (Iterator i = nestedEditors.iterator(); i.hasNext();) {
+			IEditorPart editor = (IEditorPart) i.next();
+			if (editor.isDirty()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Notifies this multi-page editor that the page with the given id has been
+	 * activated. This method is called when the user selects a different tab.
+	 * <p>
+	 * The <code>MultiPageEditorPart</code> implementation of this method sets
+	 * focus to the new page, and notifies the action bar contributor (if there
+	 * is one). This checks whether the action bar contributor is an instance of
+	 * <code>MultiPageEditorActionBarContributor</code>, and, if so, calls
+	 * <code>setActivePage</code> with the active nested editor. This also fires
+	 * a selection change event if required.
+	 * </p>
+	 * <p>
+	 * Subclasses may extend this method.
+	 * </p>
+	 * 
+	 * @param newPageIndex
+	 *            the index of the activated page
+	 */
+	protected void pageChange(int newPageIndex) {
+		deactivateSite(false, false);
+
+		IPartService partService = (IPartService) getSite().getService(
+				IPartService.class);
+		if (partService.getActivePart() == this) {
+			setFocus();
+		}
+
+		IEditorPart activeEditor = getEditor(newPageIndex);
+
+		IEditorActionBarContributor contributor = getEditorSite()
+				.getActionBarContributor();
+		if (contributor != null
+				&& contributor instanceof MultiPageEditorActionBarContributor) {
+			((MultiPageEditorActionBarContributor) contributor)
+					.setActivePage(activeEditor);
+		}
+
+		if (activeEditor != null) {
+			ISelectionProvider selectionProvider = activeEditor.getSite()
+					.getSelectionProvider();
+			if (selectionProvider != null) {
+				ISelectionProvider outerProvider = getSite()
+						.getSelectionProvider();
+				if (outerProvider instanceof MultiPageSelectionProvider) {
+					SelectionChangedEvent event = new SelectionChangedEvent(
+							selectionProvider, selectionProvider.getSelection());
+
+					MultiPageSelectionProvider provider = (MultiPageSelectionProvider) outerProvider;
+					provider.fireSelectionChanged(event);
+					provider.firePostSelectionChanged(event);
+				} else {
+					if (Policy.DEBUG_MPE) {
+						Tracing.printTrace(TRACING_COMPONENT,
+								"MultiPageEditorPart " + getTitle() //$NON-NLS-1$
+										+ " did not propogate selection for " //$NON-NLS-1$
+										+ activeEditor.getTitle());
+					}
+				}
+			}
+		}
+
+		activateSite();
+		Object selectedPage = getSelectedPage();
+		if (selectedPage != null) {
+			firePageChanged(new PageChangedEvent(this, selectedPage));
+		}
+	}
+
+	/**
+	 * This method can be used by implementors of
+	 * {@link MultiPageEditorPart#createPageContainer(Composite)} to deactivate
+	 * the active inner editor services while their header has focus. A
+	 * deactivateSite() must have a matching call to activateSite() when
+	 * appropriate.
+	 * <p>
+	 * An new inner editor will have its site activated on a
+	 * {@link MultiPageEditorPart#pageChange(int)}.
+	 * </p>
+	 * <p>
+	 * <b>Note:</b> This API is evolving in 3.4 and this might not be its final
+	 * form.
+	 * </p>
+	 * 
+	 * @param immediate
+	 *            immediately deactivate the legacy keybinding service
+	 * @param containerSiteActive
+	 *            Leave the page container site active.
+	 * @since 3.4
+	 * @see #activateSite()
+	 * @see #createPageContainer(Composite)
+	 * @see #getPageSite(int)
+	 * @see #PAGE_CONTAINER_SITE
+	 */
+	protected final void deactivateSite(boolean immediate,
+			boolean containerSiteActive) {
+		// Deactivate the nested services from the last active service locator.
+		if (activeServiceLocator != null) {
+			activeServiceLocator.deactivate();
+			activeServiceLocator = null;
+		}
+
+		final int pageIndex = getActivePage();
+		final IKeyBindingService service = getSite().getKeyBindingService();
+		if (pageIndex < 0 || pageIndex >= getPageCount() || immediate) {
+			// There is no selected page, so deactivate the active service.
+			if (service instanceof INestableKeyBindingService) {
+				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				nestableService.activateKeyBindingService(null);
+			} else {
+				WorkbenchPlugin
+						.log("MultiPageEditorPart.deactivateSite()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+
+		if (containerSiteActive) {
+			IServiceLocator containerSite = getPageContainerSite();
+			if (containerSite instanceof INestable) {
+				activeServiceLocator = (INestable) containerSite;
+				activeServiceLocator.activate();
+			}
+		}
+	}
+
+	/**
+	 * This method can be used by implementors of
+	 * {@link #createPageContainer(Composite)} to activate the active inner
+	 * editor services when their header loses focus.
+	 * <p>
+	 * An new inner editor will have its site activated on a
+	 * {@link #pageChange(int)}.
+	 * </p>
+	 * <p>
+	 * <b>Note:</b> This API is evolving in 3.4 and this might not be its final
+	 * form.
+	 * </p>
+	 * 
+	 * @since 3.4
+	 * @see #deactivateSite(boolean,boolean)
+	 * @see #createPageContainer(Composite)
+	 * @see #getPageSite(int)
+	 */
+	protected final void activateSite() {
+		if (activeServiceLocator != null) {
+			activeServiceLocator.deactivate();
+			activeServiceLocator = null;
+		}
+
+		final IKeyBindingService service = getSite().getKeyBindingService();
+		final int pageIndex = getActivePage();
+		final IEditorPart editor = getEditor(pageIndex);
+
+		if (editor != null) {
+			// active the service for this inner editor
+			if (service instanceof INestableKeyBindingService) {
+				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				nestableService.activateKeyBindingService(editor
+						.getEditorSite());
+
+			} else {
+				WorkbenchPlugin
+						.log("MultiPageEditorPart.activateSite()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			// Activate the services for the new service locator.
+			final IServiceLocator serviceLocator = editor.getEditorSite();
+			if (serviceLocator instanceof INestable) {
+				activeServiceLocator = (INestable) serviceLocator;
+				activeServiceLocator.activate();
+			}
+
+		} else {
+			Item item = getItem(pageIndex);
+
+			// There is no selected editor, so deactivate the active service.
+			if (service instanceof INestableKeyBindingService) {
+				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				nestableService.activateKeyBindingService(null);
+			} else {
+				WorkbenchPlugin
+						.log("MultiPageEditorPart.activateSite()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			if (item.getData() instanceof INestable) {
+				activeServiceLocator = (INestable) item.getData();
+				activeServiceLocator.activate();
+			}
+		}
+	}
+
+	/**
+	 * Disposes the given part and its site.
+	 * 
+	 * @param part
+	 *            The part to dispose; must not be <code>null</code>.
+	 */
+	private void disposePart(final IWorkbenchPart part) {
+		SafeRunner.run(new ISafeRunnable() {
+			public void run() {
+				IWorkbenchPartSite partSite = part.getSite();
+				part.dispose();
+				if (partSite instanceof MultiPageEditorSite) {
+					((MultiPageEditorSite) partSite).dispose();
+				}
+			}
+
+			public void handleException(Throwable e) {
+				// Exception has already being logged by Core. Do nothing.
+			}
+		});
+	}
+
+	/**
+	 * Removes the page with the given index from this multi-page editor. The
+	 * controls for the page are disposed of; if the page has an editor, it is
+	 * disposed of too. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @see MultiPageEditorPart#addPage(Control)
+	 * @see MultiPageEditorPart#addPage(IEditorPart, IEditorInput)
+	 */
+	public void removePage(int pageIndex) {
+		Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
+		// get editor (if any) before disposing item
+		IEditorPart editor = getEditor(pageIndex);
+
+		// get control for the item if it's not an editor
+		CTabItem item = getItem(pageIndex);
+		IServiceLocator pageLocator = null;
+		if (item.getData() instanceof IServiceLocator) {
+			pageLocator = (IServiceLocator) item.getData();
+		}
+		Control pageControl = item.getControl();
+
+		// dispose item before disposing editor, in case there's an exception
+		// in editor's dispose
+		item.dispose();
+
+		if (pageControl != null) {
+			pageControl.dispose();
+		}
+
+		// dispose editor (if any)
+		if (editor != null) {
+			nestedEditors.remove(editor);
+			disposePart(editor);
+		}
+		if (pageLocator != null) {
+			pageSites.remove(pageLocator);
+			if (pageLocator instanceof IDisposable) {
+				((IDisposable) pageLocator).dispose();
+			}
+		}
+	}
+
+	/**
+	 * Sets the currently active page.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page to be activated; the index must be valid
+	 */
+	protected void setActivePage(int pageIndex) {
+		Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
+		getTabFolder().setSelection(pageIndex);
+		pageChange(pageIndex);
+	}
+
+	/**
+	 * Sets the control for the given page index. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @param control
+	 *            the control for the specified page, or <code>null</code> to
+	 *            clear the control
+	 */
+	protected void setControl(int pageIndex, Control control) {
+		getItem(pageIndex).setControl(control);
+	}
+
+	/**
+	 * The <code>MultiPageEditor</code> implementation of this
+	 * <code>IWorkbenchPart</code> method sets focus on the active nested
+	 * editor, if there is one.
+	 * <p>
+	 * Subclasses may extend or reimplement.
+	 * </p>
+	 */
+	public void setFocus() {
+		setFocus(getActivePage());
+	}
+
+	/**
+	 * Sets focus to the control for the given page. If the page has an editor,
+	 * this calls its <code>setFocus()</code> method. Otherwise, this calls
+	 * <code>setFocus</code> on the control for the page.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 */
+	private void setFocus(int pageIndex) {
+		if (pageIndex < 0 || pageIndex >= getPageCount()) {
+			// page index out of bounds, don't set focus.
+			return;
+		}
+		final IEditorPart editor = getEditor(pageIndex);
+		if (editor != null) {
+			editor.setFocus();
+
+		} else {
+			// Give the page's control focus.
+			final Control control = getControl(pageIndex);
+			if (control != null) {
+				control.setFocus();
+			}
+		}
+	}
+
+	/**
+	 * Sets the image for the page with the given index, or <code>null</code> to
+	 * clear the image for the page. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @param image
+	 *            the image, or <code>null</code>
+	 */
+	protected void setPageImage(int pageIndex, Image image) {
+		getItem(pageIndex).setImage(image);
+	}
+
+	/**
+	 * Sets the text label for the page with the given index. The page index
+	 * must be valid. The text label must not be null.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @param text
+	 *            the text label
+	 */
+	protected void setPageText(int pageIndex, String text) {
+		getItem(pageIndex).setText(text);
+	}
+
+	/**
+	 * If there is an adapter registered against the subclass of
+	 * MultiPageEditorPart return that. Otherwise, delegate to the internal
+	 * editor.
+	 * 
+	 * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		Object result = super.getAdapter(adapter);
+		// restrict delegating to the UI thread for bug 144851
+		if (result == null && Display.getCurrent() != null) {
+			IEditorPart innerEditor = getActiveEditor();
+			// see bug 138823 - prevent some subclasses from causing
+			// an infinite loop
+			if (innerEditor != null && innerEditor != this) {
+				result = Util.getAdapter(innerEditor, adapter);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Find the editors contained in this multi-page editor whose editor input
+	 * match the provided input.
+	 * 
+	 * @param input
+	 *            the editor input
+	 * @return the editors contained in this multi-page editor whose editor
+	 *         input match the provided input
+	 * @since 3.3
+	 */
+	public final IEditorPart[] findEditors(IEditorInput input) {
+		List result = new ArrayList();
+		int count = getPageCount();
+		for (int i = 0; i < count; i++) {
+			IEditorPart editor = getEditor(i);
+			if (editor != null && editor.getEditorInput() != null
+					&& editor.getEditorInput().equals(input)) {
+				result.add(editor);
+			}
+		}
+		return (IEditorPart[]) result.toArray(new IEditorPart[result.size()]);
+	}
+
+	/**
+	 * Set the active page of this multi-page editor to the page that contains
+	 * the given editor part. This method has no effect of the given editor part
+	 * is not contained in this multi-page editor.
+	 * 
+	 * @param editorPart
+	 *            the editor part
+	 * @since 3.3
+	 */
+	public final void setActiveEditor(IEditorPart editorPart) {
+		int count = getPageCount();
+		for (int i = 0; i < count; i++) {
+			IEditorPart editor = getEditor(i);
+			if (editor == editorPart) {
+				setActivePage(i);
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Returns the selected page for the current active page index, either the
+	 * IEditorPart for editors or the Control for other pages.
+	 * <p>
+	 * <b>Note:</b> clients may override this method to return a page
+	 * appropriate for their editors. Maybe be <code>null</code>.
+	 * </p>
+	 * 
+	 * @return The IEditorPart or Control representing the current active page,
+	 *         or <code>null</code> if there are no active pages.
+	 * @since 3.5
+	 * @see #getActivePage()
+	 */
+	public Object getSelectedPage() {
+		int index = getActivePage();
+		if (index == -1) {
+			return null;
+		}
+		IEditorPart editor = getEditor(index);
+		if (editor != null) {
+			return editor;
+		}
+		return getControl(index);
+	}
+
+	/**
+	 * Add the page change listener to be notified when the page changes. The
+	 * newly selected page will be the Object returned from
+	 * {@link #getSelectedPage()}. In the default case, this will be the active
+	 * page Control, IEditorPart, or <code>null</code>.
+	 * <p>
+	 * This method has no effect if the listener has already been added.
+	 * </p>
+	 * 
+	 * @nooverride
+	 * 
+	 * @since 3.5
+	 */
+	public void addPageChangedListener(IPageChangedListener listener) {
+		pageChangeListeners.add(listener);
+	}
+
+	/**
+	 * Remove the page change listener.
+	 * <p>
+	 * This method has no effect if the listener is not in the list.
+	 * </p>
+	 * 
+	 * @nooverride
+	 * 
+	 * @since 3.5
+	 */
+	public void removePageChangedListener(IPageChangedListener listener) {
+		pageChangeListeners.remove(listener);
+	}
+
+	private void firePageChanged(final PageChangedEvent event) {
+		Object[] listeners = pageChangeListeners.getListeners();
+		for (int i = 0; i < listeners.length; ++i) {
+			final IPageChangedListener l = (IPageChangedListener) listeners[i];
+			SafeRunnable.run(new SafeRunnable() {
+				public void run() {
+					l.pageChanged(event);
+				}
+			});
+		}
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java
new file mode 100644
index 0000000..7f1776e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java
@@ -0,0 +1,555 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.part;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.PopupMenuExtender;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.part.IMultiPageEditorSiteHolder;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+import org.eclipse.ui.services.IServiceScopes;
+
+/**
+ * Site for a nested editor within a multi-page editor. Selection is handled by
+ * forwarding the event to the multi-page editor's selection listeners; most
+ * other methods are forwarded to the multi-page editor's site.
+ * <p>
+ * The base implementation of <code>MultiPageEditor.createSite</code> creates an
+ * instance of this class. This class may be instantiated or subclassed.
+ * </p>
+ */
+public class MultiPageEditorSite implements IEditorSite, INestable {
+
+	/**
+	 * The nested editor.
+	 */
+	private IEditorPart editor;
+
+	/**
+	 * The list of popup menu extenders; <code>null</code> if none registered.
+	 */
+	private ArrayList menuExtenders;
+
+	/**
+	 * The multi-page editor.
+	 */
+	private MultiPageEditorPart multiPageEditor;
+
+	/**
+	 * The post selection changed listener.
+	 */
+	private ISelectionChangedListener postSelectionChangedListener = null;
+
+	/**
+	 * The selection change listener, initialized lazily; <code>null</code> if
+	 * not yet created.
+	 */
+	private ISelectionChangedListener selectionChangedListener = null;
+
+	/**
+	 * The selection provider; <code>null</code> if none.
+	 * 
+	 * @see MultiPageEditorSite#setSelectionProvider(ISelectionProvider)
+	 */
+	private ISelectionProvider selectionProvider = null;
+
+	/**
+	 * The cached copy of the key binding service specific to this multi-page
+	 * editor site. This value is <code>null</code> if it is not yet
+	 * initialized.
+	 */
+	private IKeyBindingService service = null;
+
+	/**
+	 * The local service locator for this multi-page editor site. This value is
+	 * never <code>null</code>.
+	 */
+	private final ServiceLocator serviceLocator;
+
+	/**
+	 * Creates a site for the given editor nested within the given multi-page
+	 * editor.
+	 * 
+	 * @param multiPageEditor
+	 *            the multi-page editor
+	 * @param editor
+	 *            the nested editor
+	 */
+	public MultiPageEditorSite(MultiPageEditorPart multiPageEditor,
+			IEditorPart editor) {
+		Assert.isNotNull(multiPageEditor);
+		Assert.isNotNull(editor);
+		this.multiPageEditor = multiPageEditor;
+		this.editor = editor;
+
+		final IServiceLocator parentServiceLocator = multiPageEditor.getSite();
+		IServiceLocatorCreator slc = (IServiceLocatorCreator) parentServiceLocator
+				.getService(IServiceLocatorCreator.class);
+		this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+				multiPageEditor.getSite(), null, new IDisposable() {
+					public void dispose() {
+						final Control control = ((PartSite) getMultiPageEditor()
+								.getSite()).getPane().getControl();
+						if (control != null && !control.isDisposed()) {
+							((PartSite) getMultiPageEditor().getSite())
+									.getPane().doHide();
+						}
+					}
+				});
+		IEclipseContext e4Context = EclipseContextFactory.create(
+				((EditorSite) multiPageEditor.getSite()).getContext(),
+				UISchedulerStrategy.getInstance());
+		this.serviceLocator.setContext(e4Context);
+
+		initializeDefaultServices();
+	}
+
+	/**
+	 * Initialize the slave services for this site.
+	 */
+	private void initializeDefaultServices() {
+		serviceLocator.registerService(IWorkbenchLocationService.class,
+				new WorkbenchLocationService(IServiceScopes.MPESITE_SCOPE,
+						getWorkbenchWindow().getWorkbench(),
+						getWorkbenchWindow(), getMultiPageEditor().getSite(),
+						this, null, 3));
+		serviceLocator.registerService(IMultiPageEditorSiteHolder.class,
+				new IMultiPageEditorSiteHolder() {
+					public MultiPageEditorSite getSite() {
+						return MultiPageEditorSite.this;
+					}
+				});
+	}
+
+	/**
+	 * Notifies the multi page editor service that the component within which it
+	 * exists has become active.
+	 * 
+	 * @since 3.2
+	 */
+	public final void activate() {
+		serviceLocator.activate();
+	}
+
+	/**
+	 * Notifies the multi page editor service that the component within which it
+	 * exists has been deactived.
+	 * 
+	 * @since 3.2
+	 */
+	public final void deactivate() {
+		serviceLocator.deactivate();
+	}
+
+	/**
+	 * Dispose the contributions.
+	 */
+	public void dispose() {
+		if (menuExtenders != null) {
+			for (int i = 0; i < menuExtenders.size(); i++) {
+				((PopupMenuExtender) menuExtenders.get(i)).dispose();
+			}
+			menuExtenders = null;
+		}
+
+		// Remove myself from the list of nested key binding services.
+		if (service != null) {
+			IKeyBindingService parentService = getEditor().getSite()
+					.getKeyBindingService();
+			if (parentService instanceof INestableKeyBindingService) {
+				INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;
+				nestableParent.removeKeyBindingService(this);
+			}
+			service = null;
+		}
+
+		if (serviceLocator != null) {
+			serviceLocator.dispose();
+		}
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IEditorSite</code> method returns <code>null</code>, since nested
+	 * editors do not have their own action bar contributor.
+	 * 
+	 * @return <code>null</code>
+	 */
+	public IEditorActionBarContributor getActionBarContributor() {
+		return null;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IEditorSite</code> method forwards to the multi-page editor to
+	 * return the action bars.
+	 * 
+	 * @return The action bars from the parent multi-page editor.
+	 */
+	public IActionBars getActionBars() {
+		return multiPageEditor.getEditorSite().getActionBars();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		return null;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the decorator manager.
+	 * 
+	 * @return The decorator from the workbench window.
+	 * @deprecated use IWorkbench.getDecoratorManager()
+	 */
+	public ILabelDecorator getDecoratorManager() {
+		return getWorkbenchWindow().getWorkbench().getDecoratorManager()
+				.getLabelDecorator();
+	}
+
+	/**
+	 * Returns the nested editor.
+	 * 
+	 * @return the nested editor
+	 */
+	public IEditorPart getEditor() {
+		return editor;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns an empty string since the
+	 * nested editor is not created from the registry.
+	 * 
+	 * @return An empty string.
+	 */
+	public String getId() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IEditorSite.
+	 */
+	public IKeyBindingService getKeyBindingService() {
+		if (service == null) {
+			service = getMultiPageEditor().getEditorSite()
+					.getKeyBindingService();
+			if (service instanceof INestableKeyBindingService) {
+				INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				service = nestableService.getKeyBindingService(this);
+
+			} else {
+				/*
+				 * This is an internal reference, and should not be copied by
+				 * client code. If you are thinking of copying this, DON'T DO
+				 * IT.
+				 */
+				WorkbenchPlugin
+						.log("MultiPageEditorSite.getKeyBindingService()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+		return service;
+	}
+
+	/**
+	 * Returns the multi-page editor.
+	 * 
+	 * @return the multi-page editor
+	 */
+	public MultiPageEditorPart getMultiPageEditor() {
+		return multiPageEditor;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the workbench page.
+	 * 
+	 * @return The workbench page in which this editor site resides.
+	 */
+	public IWorkbenchPage getPage() {
+		return getMultiPageEditor().getSite().getPage();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartSite#getPart()
+	 */
+	public IWorkbenchPart getPart() {
+		return editor;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns an empty string since the
+	 * nested editor is not created from the registry.
+	 * 
+	 * @return An empty string.
+	 */
+	public String getPluginId() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the post selection change listener which listens to the nested
+	 * editor's selection changes.
+	 * 
+	 * @return the post selection change listener.
+	 */
+	private ISelectionChangedListener getPostSelectionChangedListener() {
+		if (postSelectionChangedListener == null) {
+			postSelectionChangedListener = new ISelectionChangedListener() {
+				public void selectionChanged(SelectionChangedEvent event) {
+					MultiPageEditorSite.this.handlePostSelectionChanged(event);
+				}
+			};
+		}
+		return postSelectionChangedListener;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns an empty string since the
+	 * nested editor is not created from the registry.
+	 * 
+	 * @return An empty string.
+	 */
+	public String getRegisteredName() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the selection changed listener which listens to the nested
+	 * editor's selection changes, and calls <code>handleSelectionChanged</code>
+	 * .
+	 * 
+	 * @return the selection changed listener
+	 */
+	private ISelectionChangedListener getSelectionChangedListener() {
+		if (selectionChangedListener == null) {
+			selectionChangedListener = new ISelectionChangedListener() {
+				public void selectionChanged(SelectionChangedEvent event) {
+					MultiPageEditorSite.this.handleSelectionChanged(event);
+				}
+			};
+		}
+		return selectionChangedListener;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns the selection provider set
+	 * by <code>setSelectionProvider</code>.
+	 * 
+	 * @return The current selection provider.
+	 */
+	public ISelectionProvider getSelectionProvider() {
+		return selectionProvider;
+	}
+
+	public final Object getService(final Class key) {
+		return serviceLocator.getService(key);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the shell.
+	 * 
+	 * @return The shell in which this editor site resides.
+	 */
+	public Shell getShell() {
+		return getMultiPageEditor().getSite().getShell();
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the workbench window.
+	 * 
+	 * @return The workbench window in which this editor site resides.
+	 */
+	public IWorkbenchWindow getWorkbenchWindow() {
+		return getMultiPageEditor().getSite().getWorkbenchWindow();
+	}
+
+	/**
+	 * Handles a post selection changed even from the nexted editor.
+	 * <p>
+	 * Subclasses may extend or reimplement this method
+	 * 
+	 * @param event
+	 *            the event
+	 * 
+	 * @since 3.2
+	 */
+	protected void handlePostSelectionChanged(SelectionChangedEvent event) {
+		ISelectionProvider parentProvider = getMultiPageEditor().getSite()
+				.getSelectionProvider();
+		if (parentProvider instanceof MultiPageSelectionProvider) {
+			SelectionChangedEvent newEvent = new SelectionChangedEvent(
+					parentProvider, event.getSelection());
+			MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
+			prov.firePostSelectionChanged(newEvent);
+		}
+	}
+
+	/**
+	 * Handles a selection changed event from the nested editor. The default
+	 * implementation gets the selection provider from the multi-page editor's
+	 * site, and calls <code>fireSelectionChanged</code> on it (only if it is an
+	 * instance of <code>MultiPageSelectionProvider</code>), passing a new event
+	 * object.
+	 * <p>
+	 * Subclasses may extend or reimplement this method.
+	 * </p>
+	 * 
+	 * @param event
+	 *            the event
+	 */
+	protected void handleSelectionChanged(SelectionChangedEvent event) {
+		ISelectionProvider parentProvider = getMultiPageEditor().getSite()
+				.getSelectionProvider();
+		if (parentProvider instanceof MultiPageSelectionProvider) {
+			SelectionChangedEvent newEvent = new SelectionChangedEvent(
+					parentProvider, event.getSelection());
+			MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
+			prov.fireSelectionChanged(newEvent);
+		}
+	}
+
+	public final boolean hasService(final Class key) {
+		return serviceLocator.hasService(key);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * for registration.
+	 * 
+	 * @param menuManager
+	 *            The menu manager
+	 * @param selProvider
+	 *            The selection provider.
+	 */
+	public void registerContextMenu(MenuManager menuManager,
+			ISelectionProvider selProvider) {
+		getMultiPageEditor().getSite().registerContextMenu(menuManager,
+				selProvider);
+	}
+
+	public final void registerContextMenu(final MenuManager menuManager,
+			final ISelectionProvider selectionProvider,
+			final boolean includeEditorInput) {
+		registerContextMenu(getId(), menuManager, selectionProvider,
+				includeEditorInput);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * for registration.
+	 * 
+	 * @param menuID
+	 *            The identifier for the menu.
+	 * @param menuMgr
+	 *            The menu manager
+	 * @param selProvider
+	 *            The selection provider.
+	 */
+	public void registerContextMenu(String menuID, MenuManager menuMgr,
+			ISelectionProvider selProvider) {
+		if (menuExtenders == null) {
+			menuExtenders = new ArrayList(1);
+		}
+		PartSite.registerContextMenu(menuID, menuMgr, selProvider, true,
+				editor, menuExtenders);
+	}
+
+	public final void registerContextMenu(final String menuId,
+			final MenuManager menuManager,
+			final ISelectionProvider selectionProvider,
+			final boolean includeEditorInput) {
+		if (menuExtenders == null) {
+			menuExtenders = new ArrayList(1);
+		}
+		PartSite.registerContextMenu(menuId, menuManager, selectionProvider,
+				includeEditorInput, editor, menuExtenders);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method remembers the selection provider,
+	 * and also hooks a listener on it, which calls
+	 * <code>handleSelectionChanged</code> when a selection changed event
+	 * occurs.
+	 * 
+	 * @param provider
+	 *            The selection provider.
+	 * @see MultiPageEditorSite#handleSelectionChanged(SelectionChangedEvent)
+	 */
+	public void setSelectionProvider(ISelectionProvider provider) {
+		ISelectionProvider oldSelectionProvider = selectionProvider;
+		selectionProvider = provider;
+		if (oldSelectionProvider != null) {
+			oldSelectionProvider
+					.removeSelectionChangedListener(getSelectionChangedListener());
+			if (oldSelectionProvider instanceof IPostSelectionProvider) {
+				((IPostSelectionProvider) oldSelectionProvider)
+						.removePostSelectionChangedListener(getPostSelectionChangedListener());
+			}
+		}
+		if (selectionProvider != null) {
+			selectionProvider
+					.addSelectionChangedListener(getSelectionChangedListener());
+			if (selectionProvider instanceof IPostSelectionProvider) {
+				((IPostSelectionProvider) selectionProvider)
+						.addPostSelectionChangedListener(getPostSelectionChangedListener());
+			}
+		}
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageBookView.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageBookView.java
new file mode 100644
index 0000000..c16171a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageBookView.java
@@ -0,0 +1,1105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.part;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.commands.common.EventManager;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.util.Util;
+
+/**
+ * Abstract superclass of all multi-page workbench views.
+ * <p>
+ * Within the workbench there are many views which track the active part. If a
+ * part is activated these views display some properties for the active part. A
+ * simple example is the <code>Outline View</code>, which displays the outline
+ * for the active editor. To avoid loss of context when part activation changes,
+ * these views may implement a multi-page approach. A separate page is
+ * maintained within the view for each source view. If a part is activated the
+ * associated page for the part is brought to top. If a part is closed the
+ * associated page is disposed. <code>PageBookView</code> is a base
+ * implementation for multi page views.
+ * </p>
+ * <p>
+ * <code>PageBookView</code>s provide an <code>IPageSite</code> for each of
+ * their pages. This site is supplied during the page's initialization. The page
+ * may supply a selection provider for this site. <code>PageBookView</code>s
+ * deal with these selection providers in a similar way to a workbench page's
+ * <code>SelectionService</code>. When a page is made visible, if its site has a
+ * selection provider, then changes in the selection are listened for and the
+ * current selection is obtained and fired as a selection change event.
+ * Selection changes are no longer listened for when a page is made invisible.
+ * </p>
+ * <p>
+ * This class should be subclassed by clients wishing to define new multi-page
+ * views.
+ * </p>
+ * <p>
+ * When a <code>PageBookView</code> is created the following methods are
+ * invoked. Subclasses must implement these.
+ * <ul>
+ * <li><code>createDefaultPage</code> - called to create a default page for the
+ * view. This page is displayed when the active part in the workbench does not
+ * have a page.</li>
+ * <li><code>getBootstrapPart</code> - called to determine the active part in
+ * the workbench. A page will be created for this part</li>
+ * </ul>
+ * </p>
+ * <p>
+ * When a part is activated the base implementation does not know if a page
+ * should be created for the part. Therefore, it delegates creation to the
+ * subclass.
+ * <ul>
+ * <li><code>isImportant</code> - called when a workbench part is activated.
+ * Subclasses return whether a page should be created for the new part.</li>
+ * <li><code>doCreatePage</code> - called to create a page for a particular part
+ * in the workbench. This is only invoked when <code>isImportant</code> returns
+ * </code>true</code>.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * When a part is closed the base implementation will destroy the page
+ * associated with the particular part. The page was created by a subclass, so
+ * the subclass must also destroy it. Subclasses must implement these.
+ * <ul>
+ * <li><code>doDestroyPage</code> - called to destroy a page for a particular
+ * part in the workbench.</li>
+ * </ul>
+ * </p>
+ */
+public abstract class PageBookView extends ViewPart implements IPartListener {
+	/**
+	 * The pagebook control, or <code>null</code> if not initialized.
+	 */
+	private PageBook book;
+
+	/**
+	 * The page record for the default page.
+	 */
+	private PageRec defaultPageRec;
+
+	/**
+	 * Map from parts to part records (key type: <code>IWorkbenchPart</code>;
+	 * value type: <code>PartRec</code>).
+	 */
+	private Map mapPartToRec = new HashMap();
+
+	/**
+	 * Map from pages to view sites Note that view sites were not added to page
+	 * recs to avoid breaking binary compatibility with previous builds
+	 */
+	private Map mapPageToSite = new HashMap();
+
+	/**
+	 * Map from pages to the number of pageRecs actively associated with a page.
+	 */
+	private Map mapPageToNumRecs = new HashMap();
+
+	/**
+	 * The page rec which provided the current page or <code>null</code>
+	 */
+	private PageRec activeRec;
+
+	/**
+	 * If the part is hidden (usually an editor) then store it so we can
+	 * continue to track it when it becomes visible.
+	 */
+	private IWorkbenchPart hiddenPart = null;
+
+	/**
+	 * The action bar property listener.
+	 */
+	private IPropertyChangeListener actionBarPropListener = new IPropertyChangeListener() {
+		public void propertyChange(PropertyChangeEvent event) {
+			if (event.getProperty().equals(SubActionBars.P_ACTION_HANDLERS)
+					&& activeRec != null
+					&& event.getSource() == activeRec.subActionBars) {
+				refreshGlobalActionHandlers();
+			}
+		}
+	};
+
+	/**
+	 * Selection change listener to listen for page selection changes
+	 */
+	private ISelectionChangedListener selectionChangedListener = new ISelectionChangedListener() {
+		public void selectionChanged(SelectionChangedEvent event) {
+			pageSelectionChanged(event);
+		}
+	};
+
+	/**
+	 * Selection change listener to listen for page selection changes
+	 */
+	private ISelectionChangedListener postSelectionListener = new ISelectionChangedListener() {
+		public void selectionChanged(SelectionChangedEvent event) {
+			postSelectionChanged(event);
+		}
+	};
+
+	/**
+	 * Selection provider for this view's site
+	 */
+	private SelectionProvider selectionProvider = new SelectionProvider();
+
+	/**
+	 * A data structure used to store the information about a single page within
+	 * a pagebook view.
+	 */
+	protected static class PageRec {
+
+		/**
+		 * The part.
+		 */
+		public IWorkbenchPart part;
+
+		/**
+		 * The page.
+		 */
+		public IPage page;
+
+		/**
+		 * The page's action bars
+		 */
+		public SubActionBars subActionBars;
+
+		/**
+		 * Creates a new page record initialized to the given part and page.
+		 * 
+		 * @param part
+		 * @param page
+		 */
+		public PageRec(IWorkbenchPart part, IPage page) {
+			this.part = part;
+			this.page = page;
+		}
+
+		/**
+		 * Disposes of this page record by <code>null</code>ing its fields.
+		 */
+		public void dispose() {
+			part = null;
+			page = null;
+		}
+	}
+
+	private static class SelectionManager extends EventManager {
+		/**
+		 * 
+		 * @param listener
+		 *            listen
+		 */
+		public void addSelectionChangedListener(
+				ISelectionChangedListener listener) {
+			addListenerObject(listener);
+		}
+
+		/**
+		 * 
+		 * @param listener
+		 *            listen
+		 */
+		public void removeSelectionChangedListener(
+				ISelectionChangedListener listener) {
+			removeListenerObject(listener);
+		}
+
+		/**
+		 * 
+		 * @param event
+		 *            the event
+		 */
+		public void selectionChanged(final SelectionChangedEvent event) {
+			// pass on the notification to listeners
+			Object[] listeners = getListeners();
+			for (int i = 0; i < listeners.length; ++i) {
+				final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
+				Platform.run(new SafeRunnable() {
+					public void run() {
+						l.selectionChanged(event);
+					}
+				});
+			}
+		}
+
+	}
+
+	/**
+	 * A selection provider/listener for this view. It is a selection provider
+	 * for this view's site.
+	 */
+	protected class SelectionProvider implements IPostSelectionProvider {
+
+		private SelectionManager fSelectionListener = new SelectionManager();
+
+		private SelectionManager fPostSelectionListeners = new SelectionManager();
+
+		/*
+		 * (non-Javadoc) Method declared on ISelectionProvider.
+		 */
+		public void addSelectionChangedListener(
+				ISelectionChangedListener listener) {
+			fSelectionListener.addSelectionChangedListener(listener);
+		}
+
+		/*
+		 * (non-Javadoc) Method declared on ISelectionProvider.
+		 */
+		public ISelection getSelection() {
+			// get the selection provider from the current page
+			IPage currentPage = getCurrentPage();
+			// during workbench startup we may be in a state when
+			// there is no current page
+			if (currentPage == null) {
+				return StructuredSelection.EMPTY;
+			}
+			IPageSite site = getPageSite(currentPage);
+			if (site == null) {
+				return StructuredSelection.EMPTY;
+			}
+			ISelectionProvider selProvider = site.getSelectionProvider();
+			if (selProvider != null) {
+				return selProvider.getSelection();
+			}
+			return StructuredSelection.EMPTY;
+		}
+
+		/*
+		 * (non-Javadoc) Method declared on ISelectionProvider.
+		 */
+		public void removeSelectionChangedListener(
+				ISelectionChangedListener listener) {
+			fSelectionListener.removeSelectionChangedListener(listener);
+		}
+
+		/**
+		 * The selection has changed. Process the event, notifying selection
+		 * listeners and post selection listeners.
+		 * 
+		 * @param event
+		 *            the change
+		 */
+		public void selectionChanged(final SelectionChangedEvent event) {
+			fSelectionListener.selectionChanged(event);
+		}
+
+		/**
+		 * The selection has changed, so notify any post-selection listeners.
+		 * 
+		 * @param event
+		 *            the change
+		 */
+		public void postSelectionChanged(final SelectionChangedEvent event) {
+			fPostSelectionListeners.selectionChanged(event);
+		}
+
+		/*
+		 * (non-Javadoc) Method declared on ISelectionProvider.
+		 */
+		public void setSelection(ISelection selection) {
+			// get the selection provider from the current page
+			IPage currentPage = getCurrentPage();
+			// during workbench startup we may be in a state when
+			// there is no current page
+			if (currentPage == null) {
+				return;
+			}
+			IPageSite site = getPageSite(currentPage);
+			if (site == null) {
+				return;
+			}
+			ISelectionProvider selProvider = site.getSelectionProvider();
+			// and set its selection
+			if (selProvider != null) {
+				selProvider.setSelection(selection);
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @seeorg.eclipse.jface.viewers.IPostSelectionProvider#
+		 * addPostSelectionChangedListener
+		 * (org.eclipse.jface.viewers.ISelectionChangedListener)
+		 */
+		public void addPostSelectionChangedListener(
+				ISelectionChangedListener listener) {
+			fPostSelectionListeners.addSelectionChangedListener(listener);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @seeorg.eclipse.jface.viewers.IPostSelectionProvider#
+		 * removePostSelectionChangedListener
+		 * (org.eclipse.jface.viewers.ISelectionChangedListener)
+		 */
+		public void removePostSelectionChangedListener(
+				ISelectionChangedListener listener) {
+			fPostSelectionListeners.removeSelectionChangedListener(listener);
+		}
+	}
+
+	/**
+	 * Creates a new pagebook view.
+	 */
+	protected PageBookView() {
+		super();
+	}
+
+	/**
+	 * Creates and returns the default page for this view.
+	 * <p>
+	 * Subclasses must implement this method.
+	 * </p>
+	 * <p>
+	 * Subclasses must call initPage with the new page (if it is an
+	 * <code>IPageBookViewPage</code>) before calling createControl on the page.
+	 * </p>
+	 * 
+	 * @param book
+	 *            the pagebook control
+	 * @return the default page
+	 */
+	protected abstract IPage createDefaultPage(PageBook book);
+
+	/**
+	 * Creates a page for a given part. Adds it to the pagebook but does not
+	 * show it.
+	 * 
+	 * @param part
+	 *            The part we are making a page for.
+	 * @return IWorkbenchPart
+	 */
+	private PageRec createPage(IWorkbenchPart part) {
+		PageRec rec = doCreatePage(part);
+		if (rec != null) {
+			mapPartToRec.put(part, rec);
+			preparePage(rec);
+		}
+		return rec;
+	}
+
+	/**
+	 * Prepares the page in the given page rec for use in this view.
+	 * 
+	 * @param rec
+	 */
+	private void preparePage(PageRec rec) {
+		IPageSite site = null;
+		Integer count;
+
+		if (!doesPageExist(rec.page)) {
+			if (rec.page instanceof IPageBookViewPage) {
+				site = ((IPageBookViewPage) rec.page).getSite();
+			}
+			if (site == null) {
+				// We will create a site for our use
+				site = new PageSite(getViewSite());
+			}
+			mapPageToSite.put(rec.page, site);
+
+			rec.subActionBars = (SubActionBars) site.getActionBars();
+			rec.subActionBars.addPropertyChangeListener(actionBarPropListener);
+			// for backward compability with IPage
+			rec.page.setActionBars(rec.subActionBars);
+
+			count = new Integer(0);
+		} else {
+			site = (IPageSite) mapPageToSite.get(rec.page);
+			rec.subActionBars = (SubActionBars) site.getActionBars();
+			count = ((Integer) mapPageToNumRecs.get(rec.page));
+		}
+
+		mapPageToNumRecs.put(rec.page, new Integer(count.intValue() + 1));
+	}
+
+	/**
+	 * Initializes the given page with a page site.
+	 * <p>
+	 * Subclasses should call this method after the page is created but before
+	 * creating its controls.
+	 * </p>
+	 * <p>
+	 * Subclasses may override
+	 * </p>
+	 * 
+	 * @param page
+	 *            The page to initialize
+	 */
+	protected void initPage(IPageBookViewPage page) {
+		try {
+			page.init(new PageSite(getViewSite()));
+		} catch (PartInitException e) {
+			WorkbenchPlugin.log(getClass(), "initPage", e); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * The <code>PageBookView</code> implementation of this
+	 * <code>IWorkbenchPart</code> method creates a <code>PageBook</code>
+	 * control with its default page showing. Subclasses may extend.
+	 */
+	public void createPartControl(Composite parent) {
+
+		// Create the page book.
+		book = new PageBook(parent, SWT.NONE);
+
+		// Create the default page rec.
+		IPage defaultPage = createDefaultPage(book);
+		defaultPageRec = new PageRec(null, defaultPage);
+		preparePage(defaultPageRec);
+
+		// Show the default page
+		showPageRec(defaultPageRec);
+
+		// Listen to part activation events.
+		getSite().getPage().addPartListener(partListener);
+		showBootstrapPart();
+	}
+
+	/**
+	 * The <code>PageBookView</code> implementation of this
+	 * <code>IWorkbenchPart</code> method cleans up all the pages. Subclasses
+	 * may extend.
+	 */
+	public void dispose() {
+		// stop listening to part activation
+		getSite().getPage().removePartListener(partListener);
+
+		// Deref all of the pages.
+		activeRec = null;
+		if (defaultPageRec != null) {
+			// check for null since the default page may not have
+			// been created (ex. perspective never visible)
+			defaultPageRec.page.dispose();
+			defaultPageRec = null;
+		}
+		Map clone = (Map) ((HashMap) mapPartToRec).clone();
+		Iterator itr = clone.values().iterator();
+		while (itr.hasNext()) {
+			PageRec rec = (PageRec) itr.next();
+			removePage(rec);
+		}
+
+		// Run super.
+		super.dispose();
+	}
+
+	/**
+	 * Creates a new page in the pagebook for a particular part. This page will
+	 * be made visible whenever the part is active, and will be destroyed with a
+	 * call to <code>doDestroyPage</code>.
+	 * <p>
+	 * Subclasses must implement this method.
+	 * </p>
+	 * <p>
+	 * Subclasses must call initPage with the new page (if it is an
+	 * <code>IPageBookViewPage</code>) before calling createControl on the page.
+	 * </p>
+	 * 
+	 * @param part
+	 *            the input part
+	 * @return the record describing a new page for this view
+	 * @see #doDestroyPage
+	 */
+	protected abstract PageRec doCreatePage(IWorkbenchPart part);
+
+	/**
+	 * Destroys a page in the pagebook for a particular part. This page was
+	 * returned as a result from <code>doCreatePage</code>.
+	 * <p>
+	 * Subclasses must implement this method.
+	 * </p>
+	 * 
+	 * @param part
+	 *            the input part
+	 * @param pageRecord
+	 *            a page record for the part
+	 * @see #doCreatePage
+	 */
+	protected abstract void doDestroyPage(IWorkbenchPart part,
+			PageRec pageRecord);
+
+	/**
+	 * Returns true if the page has already been created.
+	 * 
+	 * @param page
+	 *            the page to test
+	 * @return true if this page has already been created.
+	 */
+	protected boolean doesPageExist(IPage page) {
+		return mapPageToNumRecs.containsKey(page);
+	}
+
+	/**
+	 * The <code>PageBookView</code> implementation of this
+	 * <code>IAdaptable</code> method delegates to the current page, if it
+	 * implements <code>IAdaptable</code>.
+	 */
+	public Object getAdapter(Class key) {
+		// delegate to the current page, if supported
+		IPage page = getCurrentPage();
+		Object adapter = Util.getAdapter(page, key);
+		if (adapter != null) {
+			return adapter;
+		}
+		// if the page did not find the adapter, look for one provided by
+		// this view before delegating to super.
+		adapter = getViewAdapter(key);
+		if (adapter != null) {
+			return adapter;
+		}
+		// delegate to super
+		return super.getAdapter(key);
+	}
+
+	/**
+	 * Returns an adapter of the specified type, as provided by this view (not
+	 * the current page), or <code>null</code> if this view does not provide an
+	 * adapter of the specified adapter.
+	 * <p>
+	 * The default implementation returns <code>null</code>. Subclasses may
+	 * override.
+	 * </p>
+	 * 
+	 * @param adapter
+	 *            the adapter class to look up
+	 * @return a object castable to the given class, or <code>null</code> if
+	 *         this object does not have an adapter for the given class
+	 * @since 3.2
+	 */
+	protected Object getViewAdapter(Class adapter) {
+		return null;
+	}
+
+	/**
+	 * Returns the active, important workbench part for this view.
+	 * <p>
+	 * When the page book view is created it has no idea which part within the
+	 * workbook should be used to generate the first page. Therefore, it
+	 * delegates the choice to subclasses of <code>PageBookView</code>.
+	 * </p>
+	 * <p>
+	 * Implementors of this method should return an active, important part in
+	 * the workbench or <code>null</code> if none found.
+	 * </p>
+	 * <p>
+	 * Subclasses must implement this method.
+	 * </p>
+	 * 
+	 * @return the active important part, or <code>null</code> if none
+	 */
+	protected abstract IWorkbenchPart getBootstrapPart();
+
+	/**
+	 * Returns the part which contributed the current page to this view.
+	 * 
+	 * @return the part which contributed the current page or <code>null</code>
+	 *         if no part contributed the current page
+	 */
+	protected IWorkbenchPart getCurrentContributingPart() {
+		if (activeRec == null) {
+			return null;
+		}
+		return activeRec.part;
+	}
+
+	/**
+	 * Returns the currently visible page for this view or <code>null</code> if
+	 * no page is currently visible.
+	 * 
+	 * @return the currently visible page
+	 */
+	public IPage getCurrentPage() {
+		if (activeRec == null) {
+			return null;
+		}
+		return activeRec.page;
+	}
+
+	/**
+	 * Returns the view site for the given page of this view.
+	 * 
+	 * @param page
+	 *            the page
+	 * @return the corresponding site, or <code>null</code> if not found
+	 */
+	protected PageSite getPageSite(IPage page) {
+		return (PageSite) mapPageToSite.get(page);
+	}
+
+	/**
+	 * Returns the default page for this view.
+	 * 
+	 * @return the default page
+	 */
+	public IPage getDefaultPage() {
+		return defaultPageRec.page;
+	}
+
+	/**
+	 * Returns the pagebook control for this view.
+	 * 
+	 * @return the pagebook control, or <code>null</code> if not initialized
+	 */
+	protected PageBook getPageBook() {
+		return book;
+	}
+
+	/**
+	 * Returns the page record for the given part.
+	 * 
+	 * @param part
+	 *            the part
+	 * @return the corresponding page record, or <code>null</code> if not found
+	 */
+	protected PageRec getPageRec(IWorkbenchPart part) {
+		return (PageRec) mapPartToRec.get(part);
+	}
+
+	/**
+	 * Returns the page record for the given page of this view.
+	 * 
+	 * @param page
+	 *            the page
+	 * @return the corresponding page record, or <code>null</code> if not found
+	 */
+	protected PageRec getPageRec(IPage page) {
+		Iterator itr = mapPartToRec.values().iterator();
+		while (itr.hasNext()) {
+			PageRec rec = (PageRec) itr.next();
+			if (rec.page == page) {
+				return rec;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns whether the given part should be added to this view.
+	 * <p>
+	 * Subclasses must implement this method.
+	 * </p>
+	 * 
+	 * @param part
+	 *            the input part
+	 * @return <code>true</code> if the part is relevant, and <code>false</code>
+	 *         otherwise
+	 */
+	protected abstract boolean isImportant(IWorkbenchPart part);
+
+	/*
+	 * (non-Javadoc) Method declared on IViewPart.
+	 */
+	public void init(IViewSite site) throws PartInitException {
+		site.setSelectionProvider(selectionProvider);
+		super.init(site);
+	}
+
+	/**
+	 * The <code>PageBookView</code> implementation of this
+	 * <code>IPartListener</code> method shows the page when the given part is
+	 * activated. Subclasses may extend.
+	 */
+	public void partActivated(IWorkbenchPart part) {
+		// Is this an important part? If not just return.
+		if (!isImportant(part)) {
+			return;
+		}
+		hiddenPart = null;
+
+		// Create a page for the part.
+		PageRec rec = getPageRec(part);
+		if (rec == null) {
+			rec = createPage(part);
+		}
+
+		// Show the page.
+		if (rec != null) {
+			showPageRec(rec);
+		} else {
+			showPageRec(defaultPageRec);
+		}
+	}
+
+	/**
+	 * The <code>PageBookView</code> implementation of this
+	 * <code>IPartListener</code> method does nothing. Subclasses may extend.
+	 */
+	public void partBroughtToTop(IWorkbenchPart part) {
+		// Do nothing by default
+	}
+
+	/**
+	 * The <code>PageBookView</code> implementation of this
+	 * <code>IPartListener</code> method deal with the closing of the active
+	 * part. Subclasses may extend.
+	 */
+	public void partClosed(IWorkbenchPart part) {
+		// Update the active part.
+		if (activeRec != null && activeRec.part == part) {
+			showPageRec(defaultPageRec);
+		}
+
+		// Find and remove the part page.
+		PageRec rec = getPageRec(part);
+		if (rec != null) {
+			removePage(rec);
+		}
+		if (part == hiddenPart) {
+			hiddenPart = null;
+		}
+	}
+
+	/**
+	 * The <code>PageBookView</code> implementation of this
+	 * <code>IPartListener</code> method does nothing. Subclasses may extend.
+	 */
+	public void partDeactivated(IWorkbenchPart part) {
+		// Do nothing.
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
+	 */
+	public void partOpened(IWorkbenchPart part) {
+		// Do nothing by default.
+	}
+
+	/**
+	 * Refreshes the global actions for the active page.
+	 */
+	private void refreshGlobalActionHandlers() {
+		// Clear old actions.
+		IActionBars bars = getViewSite().getActionBars();
+		bars.clearGlobalActionHandlers();
+
+		// Set new actions.
+		Map newActionHandlers = activeRec.subActionBars
+				.getGlobalActionHandlers();
+		if (newActionHandlers != null) {
+			Set keys = newActionHandlers.entrySet();
+			Iterator iter = keys.iterator();
+			while (iter.hasNext()) {
+				Map.Entry entry = (Map.Entry) iter.next();
+				bars.setGlobalActionHandler((String) entry.getKey(),
+						(IAction) entry.getValue());
+			}
+		}
+	}
+
+	/**
+	 * Removes a page record. If it is the last reference to the page dispose of
+	 * it - otherwise just decrement the reference count.
+	 * 
+	 * @param rec
+	 */
+	private void removePage(PageRec rec) {
+		mapPartToRec.remove(rec.part);
+
+		int newCount = ((Integer) mapPageToNumRecs.get(rec.page)).intValue() - 1;
+
+		if (newCount == 0) {
+			Object site = mapPageToSite.remove(rec.page);
+			mapPageToNumRecs.remove(rec.page);
+
+			Control control = rec.page.getControl();
+			if (control != null && !control.isDisposed()) {
+				// Dispose the page's control so pages don't have to do this in
+				// their
+				// dispose method.
+				// The page's control is a child of this view's control so if
+				// this view
+				// is closed, the page's control will already be disposed.
+				control.dispose();
+			}
+
+			// free the page
+			doDestroyPage(rec.part, rec);
+
+			if (rec.subActionBars != null) {
+				rec.subActionBars.dispose();
+			}
+
+			if (site instanceof PageSite) {
+				((PageSite) site).dispose();
+			}
+		} else {
+			mapPageToNumRecs.put(rec.page, new Integer(newCount));
+		}
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWorkbenchPart.
+	 */
+	public void setFocus() {
+		// first set focus on the page book, in case the page
+		// doesn't properly handle setFocus
+		if (book != null) {
+			book.setFocus();
+		}
+		// then set focus on the page, if any
+		if (activeRec != null) {
+			activeRec.page.setFocus();
+		}
+	}
+
+	/**
+	 * Handle page selection changes.
+	 * 
+	 * @param event
+	 */
+	private void pageSelectionChanged(SelectionChangedEvent event) {
+		// forward this change from a page to our site's selection provider
+		SelectionProvider provider = (SelectionProvider) getSite()
+				.getSelectionProvider();
+		if (provider != null) {
+			provider.selectionChanged(event);
+		}
+	}
+
+	/**
+	 * Handle page selection changes.
+	 * 
+	 * @param event
+	 */
+	private void postSelectionChanged(SelectionChangedEvent event) {
+		// forward this change from a page to our site's selection provider
+		SelectionProvider provider = (SelectionProvider) getSite()
+				.getSelectionProvider();
+		if (provider != null) {
+			provider.postSelectionChanged(event);
+		}
+	}
+
+	/**
+	 * Shows a page for the active workbench part.
+	 */
+	private void showBootstrapPart() {
+		IWorkbenchPart part = getBootstrapPart();
+		if (part != null) {
+			partActivated(part);
+		}
+	}
+
+	/**
+	 * Shows page contained in the given page record in this view. The page
+	 * record must be one from this pagebook view.
+	 * <p>
+	 * The <code>PageBookView</code> implementation of this method asks the
+	 * pagebook control to show the given page's control, and records that the
+	 * given page is now current. Subclasses may extend.
+	 * </p>
+	 * 
+	 * @param pageRec
+	 *            the page record containing the page to show
+	 */
+	protected void showPageRec(PageRec pageRec) {
+		// If already showing do nothing
+		if (activeRec == pageRec) {
+			return;
+		}
+		// If the page is the same, just set activeRec to pageRec
+		if (activeRec != null && pageRec != null
+				&& activeRec.page == pageRec.page) {
+			activeRec = pageRec;
+			return;
+		}
+
+		// Hide old page.
+		if (activeRec != null) {
+			PageSite pageSite = (PageSite) mapPageToSite.get(activeRec.page);
+
+			activeRec.subActionBars.deactivate();
+
+			// deactivate the nested services
+			pageSite.deactivate();
+
+			// remove our selection listener
+			// KLUDGE!! this is a hack to get around having
+			// two Outline views...PDE editors can't handle this
+			try {
+				ISelectionProvider provider = pageSite.getSelectionProvider();
+				if (provider != null) {
+					provider
+							.removeSelectionChangedListener(selectionChangedListener);
+					if (provider instanceof IPostSelectionProvider) {
+						((IPostSelectionProvider) provider)
+								.removePostSelectionChangedListener(postSelectionListener);
+					}
+				}
+			} catch (Exception e) {
+			}
+		}
+
+		// Show new page.
+		activeRec = pageRec;
+		Control pageControl = activeRec.page.getControl();
+		if (pageControl != null && !pageControl.isDisposed()) {
+			PageSite pageSite = (PageSite) mapPageToSite.get(activeRec.page);
+
+			// Verify that the page control is not disposed
+			// If we are closing, it may have already been disposed
+			book.showPage(pageControl);
+			activeRec.subActionBars.activate();
+			refreshGlobalActionHandlers();
+
+			// activate the nested services
+			pageSite.activate();
+
+			// add our selection listener
+			ISelectionProvider provider = pageSite.getSelectionProvider();
+			if (provider != null) {
+				provider.addSelectionChangedListener(selectionChangedListener);
+				if (provider instanceof IPostSelectionProvider) {
+					((IPostSelectionProvider) provider)
+							.addPostSelectionChangedListener(postSelectionListener);
+				}
+			}
+			// Update action bars.
+			getViewSite().getActionBars().updateActionBars();
+		}
+	}
+
+	/**
+	 * Returns the selectionProvider for this page book view.
+	 * 
+	 * @return a SelectionProvider
+	 */
+	protected SelectionProvider getSelectionProvider() {
+		return selectionProvider;
+	}
+
+	private IPartListener2 partListener = new IPartListener2() {
+		public void partActivated(IWorkbenchPartReference partRef) {
+			IWorkbenchPart part = partRef.getPart(false);
+			PageBookView.this.partActivated(part);
+		}
+
+		public void partBroughtToTop(IWorkbenchPartReference partRef) {
+			PageBookView.this.partBroughtToTop(partRef.getPart(false));
+		}
+
+		public void partClosed(IWorkbenchPartReference partRef) {
+			PageBookView.this.partClosed(partRef.getPart(false));
+		}
+
+		public void partDeactivated(IWorkbenchPartReference partRef) {
+			PageBookView.this.partDeactivated(partRef.getPart(false));
+		}
+
+		public void partHidden(IWorkbenchPartReference partRef) {
+			PageBookView.this.partHidden(partRef.getPart(false));
+		}
+
+		public void partInputChanged(IWorkbenchPartReference partRef) {
+		}
+
+		public void partOpened(IWorkbenchPartReference partRef) {
+			PageBookView.this.partOpened(partRef.getPart(false));
+		}
+
+		public void partVisible(IWorkbenchPartReference partRef) {
+			PageBookView.this.partVisible(partRef.getPart(false));
+		}
+	};
+
+	/**
+	 * Make sure that the part is not considered if it is hidden.
+	 * 
+	 * @param part
+	 * @since 3.5
+	 */
+	protected void partHidden(IWorkbenchPart part) {
+		if (part == null || part != getCurrentContributingPart()) {
+			return;
+		}
+		// if we've minimized the editor stack, that's no reason to
+		// drop our content
+		if (getSite().getPage().getPartState(
+				getSite().getPage().getReference(part)) == IWorkbenchPage.STATE_MINIMIZED) {
+			return;
+		}
+		// if we're switching from a part source in our own stack,
+		// we also don't want to clear our content.
+		if (part instanceof IViewPart) {
+			final IViewPart[] viewStack = getSite().getPage()
+					.getViewStack(this);
+			if (containsPart(viewStack, part)) {
+				return;
+			}
+		}
+		hiddenPart = part;
+		showPageRec(defaultPageRec);
+	}
+
+	/**
+	 * @param viewStack
+	 * @param part
+	 * @return <code>true</code> if the part is in the viewStack
+	 */
+	private boolean containsPart(IViewPart[] viewStack, IWorkbenchPart part) {
+		if (viewStack == null) {
+			return false;
+		}
+		for (int i = 0; i < viewStack.length; i++) {
+			if (viewStack[i] == part) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Make sure that the part is not considered if it is hidden.
+	 * 
+	 * @param part
+	 * @since 3.5
+	 */
+	protected void partVisible(IWorkbenchPart part) {
+		if (part == null || part != hiddenPart) {
+			return;
+		}
+		partActivated(part);
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageSite.java
new file mode 100644
index 0000000..c401692
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageSite.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.part;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.PopupMenuExtender;
+import org.eclipse.ui.internal.ViewSite;
+import org.eclipse.ui.internal.part.IPageSiteHolder;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceScopes;
+
+/**
+ * This implementation of <code>IPageSite</code> provides a site for a page
+ * within a <code>PageBookView</code>. Most methods are forwarded to the view's
+ * site.
+ */
+public class PageSite implements IPageSite, INestable {
+
+	/**
+	 * The list of menu extender for each registered menu.
+	 */
+	private ArrayList menuExtenders;
+
+	/**
+	 * The "parent" view site
+	 */
+	private IViewSite parentSite;
+
+	/**
+	 * A selection provider set by the page. Value is <code>null</code> until
+	 * set.
+	 */
+	private ISelectionProvider selectionProvider;
+
+	/**
+	 * The localized service locator for this page site. This locator is never
+	 * <code>null</code>.
+	 */
+	private final ServiceLocator serviceLocator;
+
+	/**
+	 * The action bars for this site
+	 */
+	private SubActionBars subActionBars;
+
+	private IEclipseContext e4Context;
+
+	/**
+	 * Creates a new sub view site of the given parent view site.
+	 * 
+	 * @param parentViewSite
+	 *            the parent view site
+	 */
+	public PageSite(final IViewSite parentViewSite) {
+		Assert.isNotNull(parentViewSite);
+		parentSite = parentViewSite;
+		subActionBars = new SubActionBars(parentViewSite.getActionBars(), this);
+
+		// Initialize the service locator.
+		IServiceLocatorCreator slc = (IServiceLocatorCreator) parentSite
+				.getService(IServiceLocatorCreator.class);
+		this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+				parentViewSite, null, new IDisposable() {
+					public void dispose() {
+						final Control control = ((PartSite) parentViewSite)
+								.getPane().getControl();
+						if (control != null && !control.isDisposed()) {
+							((PartSite) parentViewSite).getPane().doHide();
+						}
+					}
+				});
+		e4Context = EclipseContextFactory.create(
+				((ViewSite) parentSite).getContext(), UISchedulerStrategy
+						.getInstance());
+		this.serviceLocator.setContext(e4Context);
+		initializeDefaultServices();
+	}
+
+	/**
+	 * Initialize the slave services for this site.
+	 */
+	private void initializeDefaultServices() {
+		serviceLocator.registerService(IWorkbenchLocationService.class,
+				new WorkbenchLocationService(IServiceScopes.PAGESITE_SCOPE,
+						getWorkbenchWindow().getWorkbench(),
+						getWorkbenchWindow(), parentSite, null, this, 3));
+		serviceLocator.registerService(IPageSiteHolder.class,
+				new IPageSiteHolder() {
+					public IPageSite getSite() {
+						return PageSite.this;
+					}
+				});
+	}
+
+	/**
+	 * Disposes of the menu extender contributions.
+	 */
+	protected void dispose() {
+		if (menuExtenders != null) {
+			HashSet managers = new HashSet(menuExtenders.size());
+			for (int i = 0; i < menuExtenders.size(); i++) {
+				PopupMenuExtender ext = (PopupMenuExtender) menuExtenders
+						.get(i);
+				managers.add(ext.getManager());
+				ext.dispose();
+			}
+			if (managers.size() > 0) {
+				for (Iterator iterator = managers.iterator(); iterator
+						.hasNext();) {
+					MenuManager mgr = (MenuManager) iterator.next();
+					mgr.dispose();
+				}
+			}
+			menuExtenders = null;
+		}
+		subActionBars.dispose();
+		serviceLocator.dispose();
+	}
+
+	/**
+	 * The PageSite implementation of this <code>IPageSite</code> method returns
+	 * the <code>SubActionBars</code> for this site.
+	 * 
+	 * @return the subactionbars for this site
+	 */
+	public IActionBars getActionBars() {
+		return subActionBars;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		return Platform.getAdapterManager().getAdapter(this, adapter);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPageSite.
+	 */
+	public IWorkbenchPage getPage() {
+		return parentSite.getPage();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPageSite.
+	 */
+	public ISelectionProvider getSelectionProvider() {
+		return selectionProvider;
+	}
+
+	public final Object getService(final Class key) {
+		return serviceLocator.getService(key);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPageSite.
+	 */
+	public Shell getShell() {
+		return parentSite.getShell();
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPageSite.
+	 */
+	public IWorkbenchWindow getWorkbenchWindow() {
+		return parentSite.getWorkbenchWindow();
+	}
+
+	public final boolean hasService(final Class key) {
+		return serviceLocator.hasService(key);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPageSite.
+	 */
+	public void registerContextMenu(String menuID, MenuManager menuMgr,
+			ISelectionProvider selProvider) {
+		if (menuExtenders == null) {
+			menuExtenders = new ArrayList(1);
+		}
+		PartSite.registerContextMenu(menuID, menuMgr, selProvider, false,
+				parentSite.getPart(), menuExtenders);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IPageSite.
+	 */
+	public void setSelectionProvider(ISelectionProvider provider) {
+		selectionProvider = provider;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.internal.services.INestable#activate()
+	 * 
+	 * @since 3.2
+	 */
+	public void activate() {
+		serviceLocator.activate();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.internal.services.INestable#deactivate()
+	 * 
+	 * @since 3.2
+	 */
+	public void deactivate() {
+		serviceLocator.deactivate();
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.project b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.project
new file mode 100644
index 0000000..2a6b80c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.e4photo.flickr.mock</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..1f4fe61
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sun Feb 14 11:25:26 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..419d88b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Mock
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.mock; singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.demo.e4photo.flickr;bundle-version="1.0.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.equinox.ds;bundle-version="1.2.0",
+ org.eclipse.e4.demo.e4photo.flickr.service;bundle-version="1.0.0",
+ org.eclipse.e4.demo.e4photo.flickr.service.rest;bundle-version="1.0.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/build.properties
new file mode 100644
index 0000000..2b0d95b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+               META-INF/,\
+               .
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/plugin.xml b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/plugin.xml
new file mode 100644
index 0000000..409a233
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+   <extension
+         id="application"
+         point="org.eclipse.core.runtime.applications">
+      <application>
+         <run
+               class="org.eclipse.e4.demo.e4photo.flickr.mock.Application">
+         </run>
+      </application>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/src/org/eclipse/e4/demo/e4photo/flickr/mock/Application.java b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/src/org/eclipse/e4/demo/e4photo/flickr/mock/Application.java
new file mode 100644
index 0000000..8995418
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/src/org/eclipse/e4/demo/e4photo/flickr/mock/Application.java
@@ -0,0 +1,48 @@
+package org.eclipse.e4.demo.e4photo.flickr.mock;
+
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.e4photo.flickr.ui.Flickr;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * This class controls all aspects of the application's execution
+ */
+public class Application implements IApplication {
+
+	public Object start(IApplicationContext context) throws Exception {
+		Display display = new Display();
+		Shell shell = new Shell();
+		
+		Bundle bundle = FrameworkUtil.getBundle(Application.class);
+		BundleContext bundleContext = bundle.getBundleContext();
+		IEclipseContext eclipseCtx = EclipseContextFactory.getServiceContext(bundleContext);
+		eclipseCtx.set(Composite.class.getName(), shell);
+		
+		ContextInjectionFactory.make(Flickr.class, eclipseCtx);
+		
+		shell.open();
+		
+		while( ! shell.isDisposed() ) {
+			if( ! display.readAndDispatch() ) {
+				display.sleep();
+			}
+		}
+		
+		display.dispose();
+		
+		return IApplication.EXIT_OK;
+	}
+
+	public void stop() {
+		// nothing to do
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.project b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.project
new file mode 100644
index 0000000..21882e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.e4photo.flickr.service.rest</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ae4a2dc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat Feb 13 18:32:38 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.pde.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..39c0d2f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Sat Feb 13 18:32:38 CET 2010
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..daa16fc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Rest
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.service.rest
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.demo.e4photo.flickr.service;bundle-version="1.0.0"
+Export-Package: org.eclipse.e4.demo.e4photo.flickr.service.rest
+Service-Component: OSGI-INF/component.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/OSGI-INF/component.xml b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/OSGI-INF/component.xml
new file mode 100644
index 0000000..57ea162
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/OSGI-INF/component.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.e4photo.flickr.service.rest">
+   <implementation class="org.eclipse.e4.demo.e4photo.flickr.service.rest.RestFlickrService"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.e4photo.flickr.service.IFlickrService"/>
+   </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/build.properties
new file mode 100644
index 0000000..fc8c47c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               OSGI-INF/component.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/JSONUtil.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/JSONUtil.java
new file mode 100644
index 0000000..47652a8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/JSONUtil.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service.rest;
+
+import java.math.BigDecimal;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.*;
+
+// JSON <--> Java
+//------------------
+// string <--> java.lang.String
+// number <--> java.math.Number (BigDecimal)
+// object <--> java.util.Map (HashMap)
+// array <--> java.util.Collection (ArrayList)
+// true <--> java.lang.Boolean.TRUE
+// false <--> java.lang.Boolean.FALSE
+// null <--> null
+
+public class JSONUtil {
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+	private static final String NULL = "null"; //$NON-NLS-1$
+
+	public static Object read(String jsonString) {
+		return parse(new StringCharacterIterator(jsonString));
+	}
+
+	public static String write(Object jsonObject) {
+		StringBuffer buffer = new StringBuffer();
+		writeValue(jsonObject, buffer);
+		return buffer.toString();
+	}
+
+	private static RuntimeException error(String message, CharacterIterator it) {
+		return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$
+	}
+
+	private static RuntimeException error(String message) {
+		return new IllegalStateException(message);
+	}
+
+	private static Object parse(CharacterIterator it) {
+		parseWhitespace(it);
+		Object result = parseValue(it);
+		parseWhitespace(it);
+
+		if (it.current() != CharacterIterator.DONE)
+			throw error("should be done", it); //$NON-NLS-1$
+		return result;
+	}
+
+	private static void parseWhitespace(CharacterIterator it) {
+		char c = it.current();
+		while (Character.isWhitespace(c))
+			c = it.next();
+	}
+
+	private static Object parseValue(CharacterIterator it) {
+		switch (it.current()) {
+			case '{' :
+				return parseObject(it);
+			case '[' :
+				return parseArray(it);
+			case '"' :
+				return parseString(it);
+			case '-' :
+			case '0' :
+			case '1' :
+			case '2' :
+			case '3' :
+			case '4' :
+			case '5' :
+			case '6' :
+			case '7' :
+			case '8' :
+			case '9' :
+				return parseNumber(it);
+			case 't' :
+				parseText(Boolean.TRUE.toString(), it);
+				return Boolean.TRUE;
+			case 'f' :
+				parseText(Boolean.FALSE.toString(), it);
+				return Boolean.FALSE;
+			case 'n' :
+				parseText(NULL, it);
+				return null;
+		}
+		throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+	}
+
+	private static Map parseObject(CharacterIterator it) {
+		it.next();
+		parseWhitespace(it);
+		if (it.current() == '}') {
+			it.next();
+			return Collections.EMPTY_MAP;
+		}
+
+		Map map = new HashMap();
+		while (true) {
+			if (it.current() != '"')
+				throw error("expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			String key = parseString(it);
+			if (map.containsKey(key))
+				throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$
+			parseWhitespace(it);
+			if (it.current() != ':')
+				throw error("expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			it.next();
+			parseWhitespace(it);
+			Object value = parseValue(it);
+			map.put(key, value);
+			parseWhitespace(it);
+			if (it.current() == ',') {
+				it.next();
+				parseWhitespace(it);
+				continue;
+			}
+
+			if (it.current() != '}')
+				throw error("expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			break;
+		}
+		it.next();
+		return map;
+	}
+
+	private static List parseArray(CharacterIterator it) {
+		it.next();
+		parseWhitespace(it);
+		if (it.current() == ']') {
+			it.next();
+			return Collections.EMPTY_LIST;
+		}
+
+		List list = new ArrayList();
+		while (true) {
+			Object value = parseValue(it);
+			list.add(value);
+			parseWhitespace(it);
+			if (it.current() == ',') {
+				it.next();
+				parseWhitespace(it);
+				continue;
+			}
+
+			if (it.current() != ']')
+				throw error("expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+			break;
+		}
+		it.next();
+		return list;
+	}
+
+	private static void parseText(String string, CharacterIterator it) {
+		int length = string.length();
+		char c = it.current();
+		for (int i = 0; i < length; i++) {
+			if (c != string.charAt(i))
+				throw error("expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$;
+			c = it.next();
+		}
+	}
+
+	private static Object parseNumber(CharacterIterator it) {
+		StringBuffer buffer = new StringBuffer();
+		char c = it.current();
+		while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E') {
+			buffer.append(c);
+			c = it.next();
+		}
+		try {
+			return new BigDecimal(buffer.toString());
+		} catch (NumberFormatException e) {
+			throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+		}
+	}
+
+	private static String parseString(CharacterIterator it) {
+		char c = it.next();
+		if (c == '"') {
+			it.next();
+			return EMPTY_STRING;
+		}
+		StringBuffer buffer = new StringBuffer();
+		while (c != '"') {
+			if (Character.isISOControl(c))
+				throw error("illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);
+
+			if (c == '\\') {
+				c = it.next();
+				switch (c) {
+					case '"' :
+					case '\\' :
+					case '/' :
+						buffer.append(c);
+						break;
+					case 'b' :
+						buffer.append('\b');
+						break;
+					case 'f' :
+						buffer.append('\f');
+						break;
+					case 'n' :
+						buffer.append('\n');
+						break;
+					case 'r' :
+						buffer.append('\r');
+						break;
+					case 't' :
+						buffer.append('\t');
+						break;
+					case 'u' :
+						StringBuffer unicode = new StringBuffer(4);
+						for (int i = 0; i < 4; i++) {
+							unicode.append(it.next());
+						}
+						try {
+							buffer.append((char) Integer.parseInt(unicode.toString(), 16));
+						} catch (NumberFormatException e) {
+							throw error("expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+						}
+						break;
+					default :
+						throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+				}
+			} else
+				buffer.append(c);
+
+			c = it.next();
+		}
+		c = it.next();
+		return buffer.toString();
+	}
+
+	private static void writeValue(Object value, StringBuffer buffer) {
+		if (value == null)
+			buffer.append(NULL);
+		else if (value instanceof Boolean || value instanceof Number)
+			buffer.append(value.toString());
+		else if (value instanceof String)
+			writeString((String) value, buffer);
+		else if (value instanceof Collection)
+			writeArray((Collection) value, buffer);
+		else if (value instanceof Map)
+			writeObject((Map) value, buffer);
+		else
+			throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+	}
+
+	private static void writeObject(Map map, StringBuffer buffer) {
+		buffer.append('{');
+		for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
+			Object key = iterator.next();
+			if (!(key instanceof String))
+				throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+			writeString((String) key, buffer);
+			buffer.append(':');
+			writeValue(map.get(key), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, '}');
+		else
+			buffer.append('}');
+	}
+
+	private static void writeArray(Collection collection, StringBuffer buffer) {
+		buffer.append('[');
+		for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+			writeValue(iterator.next(), buffer);
+			buffer.append(',');
+		}
+		if (buffer.charAt(buffer.length() - 1) == ',')
+			buffer.setCharAt(buffer.length() - 1, ']');
+		else
+			buffer.append(']');
+	}
+
+	private static void writeString(String string, StringBuffer buffer) {
+		buffer.append('"');
+		int length = string.length();
+		for (int i = 0; i < length; i++) {
+			char c = string.charAt(i);
+			switch (c) {
+				case '"' :
+				case '\\' :
+				case '/' :
+					buffer.append('\\');
+					buffer.append(c);
+					break;
+				case '\b' :
+					buffer.append("\\b"); //$NON-NLS-1$
+					break;
+				case '\f' :
+					buffer.append("\\f"); //$NON-NLS-1$
+					break;
+				case '\n' :
+					buffer.append("\\n"); //$NON-NLS-1$
+					break;
+				case '\r' :
+					buffer.append("\\r"); //$NON-NLS-1$
+					break;
+				case '\t' :
+					buffer.append("\\t"); //$NON-NLS-1$
+					break;
+				default :
+					if (Character.isISOControl(c)) {
+						buffer.append("\\u"); //$NON-NLS-1$
+						String hexString = Integer.toHexString(c);
+						for (int j = hexString.length(); j < 4; j++)
+							buffer.append('0');
+						buffer.append(hexString);
+					} else
+						buffer.append(c);
+			}
+		}
+		buffer.append('"');
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrService.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrService.java
new file mode 100644
index 0000000..6981ae1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrService.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service.rest;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrPhoto;
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrSearch;
+import org.eclipse.e4.demo.e4photo.flickr.service.IFlickrService;
+
+/**
+ * Custom implementation to access flickr through its rest API
+ */
+public class RestFlickrService implements IFlickrService {
+	
+	public RestFlickrService() {
+		System.err.println("Service created");
+	}
+	
+	public InputStream getPhoto(FlickrPhoto photo) throws RemoteException {
+		try {
+			String path = "http://farm" + photo.getFarm() + ".static.flickr.com/" + photo.getServer() + "/"+ photo.getId() + "_" + photo.getSecret() + ".jpg";
+			URL url = new URL(path);
+			return url.openStream();
+		} catch (MalformedURLException e) {
+			throw new RemoteException("Failed to fetch Flickr-Image.", e);
+		} catch (IOException e) {
+			throw new RemoteException("Failed to fetch Flickr-Image.", e);
+		}
+	}
+	
+	@SuppressWarnings("unchecked")
+	public FlickrSearch createTagSearch(String apiKey, String tags) throws RemoteException {
+		Map<String,Object> obj = searchByTagsRequest("flickr.photos.search", apiKey, tags, 1);
+		if( obj != null ) {
+			try {
+				Map<String,Object> o = (Map<String, Object>) obj.get("photos");
+				int pages = ((Number) o.get("pages")).intValue();
+				int pageSize = ((Number) o.get("perpage")).intValue();
+				int total = Integer.parseInt((String) o.get("total"));
+				return new RestFlickrTagSearch( apiKey, pages, pageSize, total, tags);
+			} catch (Exception e) {
+				throw new RemoteException("Failure while parsing response", e);
+			}	
+		}
+		
+		return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	public List<FlickrPhoto> getPhotos(FlickrSearch search, int page) throws RemoteException {
+		if( search instanceof RestFlickrTagSearch ) {
+			RestFlickrTagSearch tmp = (RestFlickrTagSearch) search;
+			Map<String,Object> root = searchByTagsRequest("flickr.photos.search", tmp.getApiKey(), tmp.getTags(), page);
+			if( root != null ) {
+				try {
+					Collection<Object> list = (Collection<Object>) ((Map<String,Object>)root.get("photos")).get("photo");
+					ArrayList<FlickrPhoto> rv = new ArrayList<FlickrPhoto>();
+					Iterator<Object> it = list.iterator();
+					
+					while( it.hasNext() ) {
+						Map<String,Object> o = (Map<String, Object>) it.next();
+						FlickrPhoto photo = new FlickrPhoto();
+						photo.setFamily( ((Number)o.get("isfamily")).intValue() != 0);
+						photo.setFarm( ((Number)o.get("farm")).intValue() );
+						photo.setFriend(((Number)o.get("isfriend")).intValue() != 0);
+						photo.setId((String) o.get("id"));
+						photo.setOwner((String) o.get("owner"));
+						photo.setPublic(((Number)o.get("ispublic")).intValue() != 0);
+						photo.setSecret((String) o.get("secret"));
+						photo.setServer((String) o.get("server"));
+						photo.setTitle((String) o.get("title"));
+						rv.add(photo);
+					}
+					return rv;
+				} catch (Exception e) {
+					throw new RemoteException("Failure while parsing response", e);
+				}	
+			}
+		}
+		
+		throw new IllegalArgumentException("The search type '"+search.getClass().getName()+"' is not supported.");
+	}
+
+	@SuppressWarnings("unchecked")
+	private Map<String,Object> searchByTagsRequest(String method, String apiKey, String tags, int page) throws RemoteException {
+		String request = "http://api.flickr.com/services/rest/";
+		request += "?tags=" + tags;
+		request += "&method=flickr.photos.search";
+		request += "&api_key="+apiKey;
+		request += "&format=json";
+		request += "&page=" + page;
+		
+		try {
+			URL url = new URL(request);
+			InputStream in = url.openStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+			String line;
+			StringBuilder b = new StringBuilder();
+			while( (line = reader.readLine()) != null ) {
+				b.append(line);
+			}
+			
+			String result = b.toString().substring("jsonFlickrApi(".length(), b.toString().length() - 1);
+			System.err.println("RESULT: " + b);
+			Map<String,Object> o = (Map<String, Object>) JSONUtil.read(result);
+			
+			if( ! "ok".equals(o.get("stat")) ) {
+				throw new RemoteException((String)o.get("message"));
+			}
+			return o;
+		} catch (RemoteException e) {
+			throw e;
+		} catch (MalformedURLException e) {
+			throw new RemoteException("Failure fetching page '"+page+"'",e); 
+		} catch (IOException e) {
+			throw new RemoteException("Failure fetching page '"+page+"'",e);
+		}
+	}
+	
+	public static void main(String[] args) {
+		try {
+			RestFlickrService s = new RestFlickrService();
+			FlickrSearch search = s.createTagSearch("46d3d5269fe6513602b3f0f06d9e2b2e", "eclipsecon");
+			
+			for( int page = 1; page <= search.getPages(); page++ ) {
+				System.err.println("--------------------------------");
+				System.err.println("Page " + page);
+				System.err.println("--------------------------------");
+				List<FlickrPhoto> photos = s.getPhotos(search, page);
+				for( FlickrPhoto p : photos ) {
+					System.err.println("	* " + p);
+				}
+			}			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrTagSearch.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrTagSearch.java
new file mode 100644
index 0000000..63fb9b7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrTagSearch.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service.rest;
+
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrSearch;
+
+public class RestFlickrTagSearch extends FlickrSearch {
+	private String tags;
+	
+	public RestFlickrTagSearch(String apiKey, int pages, int pageSize, int totalItems, String tags) {
+		super(apiKey, pages, pageSize, totalItems);
+		this.tags = tags;
+	}
+	
+	public String getTags() {
+		return tags;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.project b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.project
new file mode 100644
index 0000000..1c17d49
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.e4photo.flickr.service</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..432f96c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat Feb 13 18:30:01 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.pde.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..c8b640e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Sat Feb 13 18:30:01 CET 2010
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr.service/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a2c7fdf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Service
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.service
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.demo.e4photo.flickr.service
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr.service/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrPhoto.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrPhoto.java
new file mode 100644
index 0000000..164a46a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrPhoto.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service;
+
+/**
+ * Domain class describing a photo on flickr
+ */
+public class FlickrPhoto {
+	private String id;
+	private String owner;
+	private String secret;
+	private String server;
+	private int farm;
+	private String title;
+	private boolean isPublic;
+	private boolean isFriend;
+	private boolean isFamily;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getOwner() {
+		return owner;
+	}
+
+	public void setOwner(String owner) {
+		this.owner = owner;
+	}
+
+	public String getSecret() {
+		return secret;
+	}
+
+	public void setSecret(String secret) {
+		this.secret = secret;
+	}
+
+	public String getServer() {
+		return server;
+	}
+
+	public void setServer(String server) {
+		this.server = server;
+	}
+
+	public int getFarm() {
+		return farm;
+	}
+
+	public void setFarm(int farm) {
+		this.farm = farm;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public boolean isPublic() {
+		return isPublic;
+	}
+
+	public void setPublic(boolean isPublic) {
+		this.isPublic = isPublic;
+	}
+
+	public boolean isFriend() {
+		return isFriend;
+	}
+
+	public void setFriend(boolean isFriend) {
+		this.isFriend = isFriend;
+	}
+
+	public boolean isFamily() {
+		return isFamily;
+	}
+
+	public void setFamily(boolean isFamily) {
+		this.isFamily = isFamily;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrSearch.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrSearch.java
new file mode 100644
index 0000000..ba65612
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrSearch.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service;
+
+/**
+ * Represents a flickr search which is used to access search pages
+ */
+public class FlickrSearch {
+	private int pages;
+	private int pageSize;
+	private int totalItems;
+	private String apiKey;
+
+	public FlickrSearch(String apiKey, int pages, int pageSize, int totalItems) {
+		this.apiKey = apiKey;
+		this.pages = pages;
+		this.pageSize = pageSize;
+		this.totalItems = totalItems;
+	}
+
+	public int getPages() {
+		return pages;
+	}
+
+	public String getApiKey() {
+		return apiKey;
+	}
+
+	public int getPageSize() {
+		return pageSize;
+	}
+
+	public int getTotalItems() {
+		return totalItems;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/IFlickrService.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/IFlickrService.java
new file mode 100644
index 0000000..8d75e8d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/IFlickrService.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service;
+
+import java.io.InputStream;
+import java.rmi.RemoteException;
+import java.util.List;
+
+/**
+ * Service interface to access flickr
+ */
+public interface IFlickrService {
+	public FlickrSearch createTagSearch(String apiKey, String tags) throws RemoteException;
+	
+	public List<FlickrPhoto> getPhotos(FlickrSearch search, int page) throws RemoteException;
+	
+	public InputStream getPhoto(FlickrPhoto photo) throws RemoteException;
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.project b/examples/org.eclipse.e4.demo.e4photo.flickr/.project
new file mode 100644
index 0000000..d4e510c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.e4photo.flickr</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..fa5bc6c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat Feb 13 17:18:20 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.pde.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..2ad4a73
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Sat Feb 13 17:44:58 CET 2010
+eclipse.preferences.version=1
+pluginProject.extensions=true
+resolve.requirebundle=false
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..51c915f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Flickr
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ javax.inject;bundle-version="1.0.0",
+ org.eclipse.e4.demo.e4photo.flickr.service;bundle-version="1.0.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0"
+Export-Package: org.eclipse.e4.demo.e4photo.flickr.ui;x-friends:="org.eclipse.e4.demo.e4photo.flickr.mock"
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/about.html b/examples/org.eclipse.e4.demo.e4photo.flickr/about.html
new file mode 100644
index 0000000..c1343aa
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/about.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>December 3, 2009</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Third Party Content</h3>
+
+<p>The Content includes items  from third parties as set out below. If you did not
+receive this Content directly from the Eclipse Foundation, the following is provided for informational
+purposes only, and you should look to the Redistributor&rsquo;s license for terms and conditions of use.</p>
+
+<h4>Silk icon set Version 1.3</h4>
+<p>
+This plugin contains icons from the Silk icon set created by Mark James. The original files can
+be found at:
+<ul>
+<a href="http://www.famfamfam.com/lab/icons/silk/">http://www.famfamfam.com/lab/icons/silk/</a></ul>
+<p>The license can be found at:</p>
+<ul>
+ <li><a href="http://creativecommons.org/licenses/by/2.5/">http://creativecommons.org/licenses/by/2.5/</a></li>
+</ul>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr/build.properties
new file mode 100644
index 0000000..7ae8bc7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               xmi/
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/accept.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/accept.png
new file mode 100644
index 0000000..89c8129
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/accept.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_end_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_end_blue.png
new file mode 100644
index 0000000..7207935
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_end_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_fastforward_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_fastforward_blue.png
new file mode 100644
index 0000000..4a2f9d4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_fastforward_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_rewind_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_rewind_blue.png
new file mode 100644
index 0000000..15d1584
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_rewind_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_start_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_start_blue.png
new file mode 100644
index 0000000..6f11fcb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_start_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/exclamation.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/exclamation.png
new file mode 100644
index 0000000..c37bd06
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/exclamation.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/plugin.xml b/examples/org.eclipse.e4.demo.e4photo.flickr/plugin.xml
new file mode 100644
index 0000000..b39876c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id2"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/Flickr.java b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/Flickr.java
new file mode 100644
index 0000000..e0368b6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/Flickr.java
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.ui;
+
+import java.rmi.RemoteException;
+import java.util.Collections;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrPhoto;
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrSearch;
+import org.eclipse.e4.demo.e4photo.flickr.service.IFlickrService;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.jface.window.ToolTip;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Search for images on flickr.com
+ */
+public class Flickr {
+	@Inject
+	private IFlickrService flickrService;
+	
+	private Composite comp;
+	
+	private PagedTable<FlickrPhoto> table;
+	
+	@Inject
+	public Flickr(Composite comp) {
+		this.comp = comp;
+		comp.setLayout(new GridLayout(3, false));
+		
+		final Image OK_IMG = new Image(comp.getDisplay(), getClass().getClassLoader().getResourceAsStream("icons/accept.png"));
+		final Image NOK_IMG = new Image(comp.getDisplay(), getClass().getClassLoader().getResourceAsStream("icons/exclamation.png"));
+		
+		comp.addDisposeListener(new DisposeListener() {
+			
+			public void widgetDisposed(DisposeEvent e) {
+				OK_IMG.dispose();
+				NOK_IMG.dispose();
+			}
+		});
+		
+		comp.setBackgroundMode(SWT.INHERIT_DEFAULT);
+		
+		Label l = new Label(comp, SWT.NONE);
+		l.setText("Flickr API-Key");
+		l.setLayoutData(new GridData(SWT.DEFAULT,GridData.CENTER,false,false));
+		
+		final Text apiKey = new Text(comp, SWT.BORDER);
+		apiKey.setLayoutData(new GridData(GridData.FILL,GridData.CENTER,true,false,2,1));
+		apiKey.setText("46d3d5269fe6513602b3f0f06d9e2b2e");
+		
+		l = new Label(comp, SWT.NONE);
+		l.setText("Search Tags");
+		l.setLayoutData(new GridData(SWT.DEFAULT,GridData.CENTER,false,false));
+		
+		final Text tags = new Text(comp, SWT.BORDER);
+		tags.setLayoutData(new GridData(GridData.FILL,GridData.CENTER,true,false));
+		tags.setText("eclipsecon");
+		
+		Button button = new Button(comp, SWT.PUSH);
+		button.setText("Search");
+		
+		table = new PagedTable<FlickrPhoto>(comp, SWT.NONE);
+		
+		button.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				handleSearch(apiKey.getText(), tags.getText());
+			}
+		});
+		
+		table.addColumn("Id", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+			@Override
+			protected String doGetText(FlickrPhoto element) {
+				return element.getId();
+			}
+		},new ColumnPixelData(120));
+		table.addColumn("Title", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+			@Override
+			protected String doGetText(FlickrPhoto element) {
+				return element.getTitle();
+			}
+			
+			@Override
+			protected String doGetToolTipText(FlickrPhoto element) {
+				return element.getId() +  " - " + element.getTitle();
+			}
+		},new ColumnWeightData(1));
+		table.addColumn("Public", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+			@Override
+			protected Image doGetImage(FlickrPhoto element) {
+				if( element.isPublic() ) {
+					return OK_IMG;
+				} else {
+					return NOK_IMG;
+				}
+			}
+			
+			@Override
+			protected String doGetText(FlickrPhoto element) {
+				return "";
+			}
+		},new ColumnPixelData(50));
+		
+		table.addColumn("Friend", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+			@Override
+			protected Image doGetImage(FlickrPhoto element) {
+				if( element.isFriend() ) {
+					return OK_IMG;
+				} else {
+					return NOK_IMG;
+				}
+			}
+			@Override
+			protected String doGetText(FlickrPhoto element) {
+				return "";
+			}
+
+		},new ColumnPixelData(50));
+		
+		table.addColumn("Family", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+			@Override
+			protected Image doGetImage(FlickrPhoto element) {
+				if( element.isFamily() ) {
+					return OK_IMG;
+				} else {
+					return NOK_IMG;
+				}
+			}
+			@Override
+			protected String doGetText(FlickrPhoto element) {
+				return "";
+			}
+
+		},new ColumnPixelData(50));
+		
+		table.setLayoutData(new GridData(GridData.FILL,GridData.FILL,true,true,3,1));
+		
+		new ToolTipSupport(table.getViewer(), ToolTip.NO_RECREATE, false);
+	}
+	
+	private void handleSearch(String apiKey, String tags) {
+		try {
+			FlickrSearch search = flickrService.createTagSearch(apiKey, tags);
+			table.setInput(new SearchInput(search));
+		} catch (RemoteException e1) {
+			Status s = new Status(IStatus.ERROR, "org.eclipse.e4.demo.e4photo.flickr", e1.getMessage(), e1);
+			ErrorDialog.openError(table.getShell(), "Searchfailure", "Failure while executing search", s);
+		}
+	}
+	
+	private class ToolTipSupport extends ColumnViewerToolTipSupport {
+
+		protected ToolTipSupport(ColumnViewer viewer, int style,
+				boolean manualActivation) {
+			super(viewer, style, manualActivation);
+		}
+		
+		@Override
+		protected Composite createViewerToolTipContentArea(Event event,
+				ViewerCell cell, final Composite parent) {
+			Composite comp = new Composite(parent, SWT.NONE);
+			
+			parent.setBackgroundMode(SWT.INHERIT_DEFAULT);
+			if( cell == null || cell.getElement() == null ) {
+				return comp;
+			}
+			final FlickrPhoto photo = (FlickrPhoto) cell.getElement();
+			
+			comp.setLayout(new GridLayout());
+			Label l = new Label(comp, SWT.NONE);
+			l.setText(getText(event));
+			l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			
+			l = new Label(comp, SWT.SEPARATOR | SWT.HORIZONTAL);
+			l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			
+			final Label img = new Label(comp, SWT.NONE);
+			
+			Thread t = new Thread() {
+				public void run() {
+					if( parent.isDisposed() ) {
+						return;
+					}
+					
+					parent.getDisplay().syncExec(new Runnable() {
+						
+						public void run() {
+							if( img.isDisposed() ) {
+								return;
+							}
+							
+							try {
+								img.setImage(new Image(parent.getDisplay(), flickrService.getPhoto(photo)));
+							} catch (RemoteException e) {
+								img.setText("Failed to fetch image from remote server.");
+							}
+							parent.getShell().pack(true);
+						}
+					});
+				}
+			};
+			
+			t.start();
+			
+			img.addDisposeListener(new DisposeListener() {
+				
+				public void widgetDisposed(DisposeEvent e) {
+					if( img.getImage() != null ) {
+						img.getImage().dispose();
+					}
+				}
+			});
+			
+			return comp;
+		}
+		
+	}
+	
+	private class SearchInput implements IPagedInput<FlickrPhoto> {
+		private FlickrSearch search;
+		
+		public SearchInput(FlickrSearch search) {
+			this.search = search;
+		}
+		
+		public int getPages() {
+			return search.getPages();
+		}
+
+		public int getPageSize() {
+			return search.getPageSize();
+		}
+
+		public int getTotalItems() {
+			return search.getTotalItems();
+		}
+
+		public List<FlickrPhoto> getItems(int page) {
+			try {
+				return flickrService.getPhotos(search, page);
+			} catch (RemoteException e) {
+				Status s = new Status(IStatus.ERROR, "org.eclipse.e4.demo.e4photo.flickr", e.getMessage(), e);
+				ErrorDialog.openError(comp.getShell(), "Searchfailure", "Failure while fetching photo page", s);
+			}
+			
+			return Collections.emptyList();
+		}
+		
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/IPagedInput.java b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/IPagedInput.java
new file mode 100644
index 0000000..dbeb6ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/IPagedInput.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.ui;
+
+import java.util.List;
+
+/**
+ * Input for the paged table
+ * 
+ * @param <M>
+ *            the paged table
+ */
+public interface IPagedInput<M> {
+	/**
+	 * @return the number of pages
+	 */
+	public int getPages();
+
+	/**
+	 * @return the number of elements per page
+	 */
+	public int getPageSize();
+
+	/**
+	 * @return the number of total items per page
+	 */
+	public int getTotalItems();
+
+	/**
+	 * Get the items of the page
+	 * 
+	 * @param page
+	 *            the page
+	 * @return the items
+	 */
+	public List<M> getItems(int page);
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/PagedTable.java b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/PagedTable.java
new file mode 100644
index 0000000..4be7fe8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/PagedTable.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.ui;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A table which shows it's items in a paged list
+ * 
+ * @param <M> the object type
+ */
+public class PagedTable<M> extends Composite {
+	private TableViewer viewer;
+	private IPagedInput<M> input;
+	private Label pageLabel;
+	private TableColumnLayout tblLayout;
+	private Composite layoutFooter;
+	private Composite progressComp;
+	private Text pageField;
+	private int currentPage;
+
+	public PagedTable(Composite parent, int style) {
+		super(parent, style);
+		setLayout(new GridLayout());
+
+		Composite tabelContainer = new Composite(this, SWT.NONE);
+		tabelContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
+		tblLayout = new TableColumnLayout();
+		tabelContainer.setLayout(tblLayout);
+
+		viewer = new TableViewer(tabelContainer);
+		viewer.getTable().setHeaderVisible(true);
+
+		layoutFooter = new Composite(this, SWT.NONE);
+		layoutFooter.setLayout(new GridLayout(2, false));
+		layoutFooter.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		Composite navigation = new Composite(layoutFooter, SWT.NONE);
+		navigation.setLayout(new GridLayout(8, false));
+
+		Image imgFirst = new Image(navigation.getDisplay(), getClass()
+				.getClassLoader().getResourceAsStream(
+						"icons/control_start_blue.png"));
+		Image imgPrev = new Image(navigation.getDisplay(), getClass()
+				.getClassLoader().getResourceAsStream(
+						"icons/control_rewind_blue.png"));
+		Image imgNext = new Image(navigation.getDisplay(), getClass()
+				.getClassLoader().getResourceAsStream(
+						"icons/control_fastforward_blue.png"));
+		Image imgLast = new Image(navigation.getDisplay(), getClass()
+				.getClassLoader().getResourceAsStream(
+						"icons/control_end_blue.png"));
+
+		Button b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+		b.setImage(imgFirst);
+		b.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (input != null) {
+					showPage(1);
+				}
+			}
+		});
+
+		b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+		b.setImage(imgPrev);
+		b.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (currentPage > 1) {
+					if (input != null) {
+						showPage(--currentPage);
+					}
+				}
+
+			}
+		});
+
+		Label l = new Label(navigation, SWT.NONE);
+		l.setText("Page");
+
+		pageField = new Text(navigation, SWT.BORDER);
+		GridData gd = new GridData(50, SWT.DEFAULT);
+		gd.verticalAlignment = SWT.CENTER;
+		pageField.setLayoutData(gd);
+		pageField.addFocusListener(new FocusAdapter() {
+			@Override
+			public void focusLost(FocusEvent e) {
+				try {
+					if (input != null) {
+						int i = Integer.parseInt(pageField.getText());
+						if (i >= 1 && i <= input.getPages()) {
+							showPage(i);
+						} else {
+							pageField.setText(currentPage+"");
+						}
+					}
+				} catch (Exception ex) {
+					Status s = new Status(IStatus.ERROR, "org.eclipse.e4.demo.e4photo.flickr", ex.getMessage(), ex);
+					ErrorDialog.openError(pageField.getShell(), "Invalid number", "The entere value is not a valid page number", s);
+					pageField.setText(currentPage+"");
+				}
+
+			}
+		});
+
+		pageLabel = new Label(navigation, SWT.NONE);
+		pageLabel.setText("of ");
+
+		b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+		b.setImage(imgNext);
+		b.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (input != null) {
+					if (currentPage < input.getPages()) {
+						showPage(++currentPage);
+					}
+				}
+			}
+		});
+
+		b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+		b.setImage(imgLast);
+		b.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				if (input != null) {
+					showPage(input.getPages());
+				}
+			}
+		});
+
+		progressComp = new Composite(this, SWT.NONE);
+		progressComp.setLayout(new GridLayout(2, false));
+		progressComp.setVisible(false);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.exclude = true;
+		progressComp.setLayoutData(gd);
+
+		l = new Label(progressComp, SWT.NONE);
+		l.setText("Loading");
+
+		ProgressBar progress = new ProgressBar(progressComp, SWT.INDETERMINATE);
+		progress.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		viewer.setContentProvider(new ArrayContentProvider());
+	}
+
+	public ColumnViewer getViewer() {
+		return viewer;
+	}
+
+	public void addColumn(String label, PageColumnLabelProvider<M> labelProvider,
+			ColumnLayoutData layoutData) {
+		TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
+		column.getColumn().setText(label);
+		column.setLabelProvider(labelProvider);
+		tblLayout.setColumnData(column.getColumn(), layoutData);
+	}
+
+	public void setInput(IPagedInput<M> input) {
+		this.input = input;
+		pageLabel.setText("of " + input.getPages());
+		showPage(1);
+	}
+
+	public void showPage(final int page) {
+		((GridData) layoutFooter.getLayoutData()).exclude = true;
+		((GridData) progressComp.getLayoutData()).exclude = false;
+		layoutFooter.setVisible(false);
+		progressComp.setVisible(true);
+		layout(true, true);
+		Thread t = new Thread() {
+			@Override
+			public void run() {
+				final List<M> list = input.getItems(page);
+				getDisplay().syncExec(new Runnable() {
+
+					public void run() {
+						currentPage = page;
+						((GridData) layoutFooter.getLayoutData()).exclude = false;
+						((GridData) progressComp.getLayoutData()).exclude = true;
+						layoutFooter.setVisible(true);
+						progressComp.setVisible(false);
+						layout(true, true);
+						viewer.setInput(list);
+						pageField.setText(page + "");
+					}
+				});
+			}
+		};
+		t.start();
+	}
+	
+	public static class PageColumnLabelProvider<M> extends ColumnLabelProvider {
+		@SuppressWarnings("unchecked")
+		@Override
+		public final String getText(Object element) {
+			return doGetText((M) element);
+		}
+		
+		protected String doGetText(M element) {
+			return super.getText(element);
+		}
+		
+		@SuppressWarnings("unchecked")
+		@Override
+		public final Image getImage(Object element) {
+			return doGetImage((M) element);
+		}
+		
+		protected Image doGetImage(M element) {
+			return super.getImage(element);
+		}
+		
+		@SuppressWarnings("unchecked")
+		@Override
+		public String getToolTipText(Object element) {
+			return doGetToolTipText((M) element);
+		}
+		
+		protected String doGetToolTipText(M element) {
+			return super.getToolTipText(element);
+		}
+	}
+	
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/components.e4xmi b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/components.e4xmi
new file mode 100644
index 0000000..fc6e480
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/components.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:ModelComponents xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2008/UIModel" xsi:schemaLocation="http://www.eclipse.org/ui/2008/UIModel ../../org.eclipse.e4.ui.model.workbench/model/UIElements.ecore" xmi:id="_UW9TZfr3Ed6gmo7caOxU9h">
+  <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9q" id="" parentID="_AXU5Wu8IEd6FC9cDb6iV7g">
+    <children xsi:type="application:Part" id="flickrView" URI="bundleclass://org.eclipse.e4.demo.e4photo.flickr/org.eclipse.e4.demo.e4photo.flickr.ui.Flickr" persistedState="" label="Flickr Search"/>
+  </components>
+</application:ModelComponents>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/fragment.e4xmi
new file mode 100644
index 0000000..6bed8a5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/fragment.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_BVHewHimEd-BhZHV_Fwq8Q">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_PoZXIHimEd-cPe0oSIgEPQ" featurename="children" parentElementId="_sRLYgEleEd-TVO58rzJVgA">
+    <elements xsi:type="basic:Part" xmi:id="_ZyE84HimEd-cPe0oSIgEPQ" contributionURI="bundleclass://org.eclipse.e4.demo.e4photo.flickr/org.eclipse.e4.demo.e4photo.flickr.ui.Flickr" label="Flickr Search"/>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.log/.classpath b/examples/org.eclipse.e4.demo.log/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.log/.project b/examples/org.eclipse.e4.demo.log/.project
new file mode 100644
index 0000000..25d5b1a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.log</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.log/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.log/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..1956c7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Tue Mar 16 13:43:58 EDT 2010
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/examples/org.eclipse.e4.demo.log/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.log/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8395b33
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: e4 Demo Log
+Bundle-SymbolicName: org.eclipse.e4.demo.log;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.e4.demo.log.Activator
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.core.commands.common,
+ org.eclipse.core.commands.contexts,
+ org.eclipse.e4.core.contexts,
+ org.eclipse.e4.core.di,
+ org.eclipse.e4.core.di.annotations,
+ org.eclipse.e4.core.services.events,
+ org.eclipse.e4.ui.bindings,
+ org.eclipse.e4.ui.bindings.internal,
+ org.eclipse.e4.ui.model.application,
+ org.eclipse.e4.ui.services,
+ org.eclipse.jface.viewers,
+ org.eclipse.swt,
+ org.eclipse.swt.custom,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.osgi.framework;version="1.5.0"
+Require-Bundle: org.eclipse.e4.ui.workbench
diff --git a/examples/org.eclipse.e4.demo.log/build.properties b/examples/org.eclipse.e4.demo.log/build.properties
new file mode 100644
index 0000000..173713b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               xmi/,\
+               css/
diff --git a/examples/org.eclipse.e4.demo.log/css/default.css b/examples/org.eclipse.e4.demo.log/css/default.css
new file mode 100644
index 0000000..463625d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/css/default.css
@@ -0,0 +1,88 @@
+CTabFolder {
+	simple: true;
+	margin: 3;
+}
+
+CTabItem {
+	font: Verdana 8px;
+	color: #666666;
+	background-color: #ffffff;
+}
+CTabItem:selected {
+	background-color: #f4f4f4;
+}
+
+CTabItem.active {
+	background-color: #ffffff;
+}
+
+CTabItem.active:selected {
+	color: #ff5500;
+	background-color: #f4f4f4;
+	font-weight: bold;
+}
+
+#library {
+	background-color: #f4f4f4;
+}
+
+#preview {
+	color: #e5e5e5;
+	background-color: #ffffff;
+}
+
+.keyContextView#me {
+	color: #ff00ff;
+	background-color: #ffffff;
+}
+
+.keyContextView#app {
+	color: #ff5500;
+	background-color: #f4f4f4;
+}
+
+
+Gallery {
+	background-color: #f4f4f4;
+}
+
+GalleryItem:selected {
+	background-color: #ff884c;
+}
+
+
+#location {
+	background-color: #f4f4f4;
+}
+
+ToolBar {
+	color: #666666;
+	font: Verdana 8px;
+	background-color: #fffff3;
+}
+
+ToolItem {
+	color: #666666;
+	background-color: #fffff3;
+}
+	
+SashForm {
+	background-color: white;
+}
+
+Text {
+	font: Verdana 8px;
+}      
+
+Label {
+	font: Verdana 8px;
+}
+
+Tree {
+	font: Verdana 8px;
+	color: #666666;
+}
+
+Composite, Shell {
+	background-color: #ffffff;
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.log/e4-view-demo.product b/examples/org.eclipse.e4.demo.log/e4-view-demo.product
new file mode 100644
index 0000000..e095a6d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/e4-view-demo.product
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="Eclipse 4 IDE" id="org.eclipse.e4.demo.log.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" version="1.0.0.qualifier" useFeatures="false" includeLaunchers="true">
+
+   <configIni use="default">
+   </configIni>
+
+   <launcherArgs>
+      <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+   </launcherArgs>
+
+   <windowImages/>
+
+   <plugins>
+      <plugin id="com.ibm.icu"/>
+      <plugin id="javax.inject"/>
+      <plugin id="javax.servlet"/>
+      <plugin id="org.apache.batik.css"/>
+      <plugin id="org.apache.batik.util"/>
+      <plugin id="org.apache.batik.util.gui"/>
+      <plugin id="org.apache.commons.beanutils"/>
+      <plugin id="org.apache.commons.logging"/>
+      <plugin id="org.eclipse.ant.core"/>
+      <plugin id="org.eclipse.core.commands"/>
+      <plugin id="org.eclipse.core.contenttype"/>
+      <plugin id="org.eclipse.core.databinding"/>
+      <plugin id="org.eclipse.core.databinding.beans"/>
+      <plugin id="org.eclipse.core.databinding.observable"/>
+      <plugin id="org.eclipse.core.databinding.property"/>
+      <plugin id="org.eclipse.core.expressions"/>
+      <plugin id="org.eclipse.core.filesystem"/>
+      <plugin id="org.eclipse.core.filesystem.hpux.PA_RISC" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.hpux.ia64_32" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.linux.ppc" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.linux.x86" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.linux.x86_64" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.macosx" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.qnx.x86" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.solaris.sparc" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.win32.ia64" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.win32.x86" fragment="true"/>
+      <plugin id="org.eclipse.core.jobs"/>
+      <plugin id="org.eclipse.core.resources"/>
+      <plugin id="org.eclipse.core.resources.compatibility" fragment="true"/>
+      <plugin id="org.eclipse.core.resources.win32.ia64" fragment="true"/>
+      <plugin id="org.eclipse.core.resources.win32.x86" fragment="true"/>
+      <plugin id="org.eclipse.core.runtime"/>
+      <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
+      <plugin id="org.eclipse.core.variables"/>
+      <plugin id="org.eclipse.e4.core.commands"/>
+      <plugin id="org.eclipse.e4.core.services"/>
+      <plugin id="org.eclipse.e4.core.services.annotations" fragment="true"/>
+      <plugin id="org.eclipse.e4.demo.e4photo"/>
+      <plugin id="org.eclipse.e4.demo.log"/>
+      <plugin id="org.eclipse.e4.ide.application"/>
+      <plugin id="org.eclipse.e4.ui.bindings"/>
+      <plugin id="org.eclipse.e4.ui.css.core"/>
+      <plugin id="org.eclipse.e4.ui.css.nebula"/>
+      <plugin id="org.eclipse.e4.ui.css.swt"/>
+      <plugin id="org.eclipse.e4.ui.model.workbench"/>
+      <plugin id="org.eclipse.e4.ui.services"/>
+      <plugin id="org.eclipse.e4.ui.workbench"/>
+      <plugin id="org.eclipse.e4.ui.workbench.renderers.swt"/>
+      <plugin id="org.eclipse.e4.ui.workbench.renderers.swt.contributions"/>
+      <plugin id="org.eclipse.e4.ui.workbench.swt"/>
+      <plugin id="org.eclipse.e4.ui.workbench3"/>
+      <plugin id="org.eclipse.emf.common"/>
+      <plugin id="org.eclipse.emf.databinding"/>
+      <plugin id="org.eclipse.emf.ecore"/>
+      <plugin id="org.eclipse.emf.ecore.change"/>
+      <plugin id="org.eclipse.emf.ecore.xmi"/>
+      <plugin id="org.eclipse.equinox.app"/>
+      <plugin id="org.eclipse.equinox.common"/>
+      <plugin id="org.eclipse.equinox.concurrent"/>
+      <plugin id="org.eclipse.equinox.ds"/>
+      <plugin id="org.eclipse.equinox.event"/>
+      <plugin id="org.eclipse.equinox.preferences"/>
+      <plugin id="org.eclipse.equinox.registry"/>
+      <plugin id="org.eclipse.equinox.util"/>
+      <plugin id="org.eclipse.jface"/>
+      <plugin id="org.eclipse.jface.databinding"/>
+      <plugin id="org.eclipse.nebula.widgets.gallery"/>
+      <plugin id="org.eclipse.osgi"/>
+      <plugin id="org.eclipse.osgi.services"/>
+      <plugin id="org.eclipse.swt"/>
+      <plugin id="org.eclipse.swt.carbon.macosx" fragment="true"/>
+      <plugin id="org.eclipse.swt.cocoa.macosx" fragment="true"/>
+      <plugin id="org.eclipse.swt.cocoa.macosx.x86_64" fragment="true"/>
+      <plugin id="org.eclipse.swt.gtk.linux.x86" fragment="true"/>
+      <plugin id="org.eclipse.swt.win32.win32.x86" fragment="true"/>
+      <plugin id="org.w3c.css.sac"/>
+      <plugin id="org.w3c.dom.smil"/>
+      <plugin id="org.w3c.dom.svg"/>
+   </plugins>
+
+
+</product>
diff --git a/examples/org.eclipse.e4.demo.log/plugin.xml b/examples/org.eclipse.e4.demo.log/plugin.xml
new file mode 100644
index 0000000..a9cf293
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/plugin.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="product"
+         point="org.eclipse.core.runtime.products">
+      <product
+            application="org.eclipse.e4.ui.workbench.swt.E4Application"
+            description="Based on e4"
+            name="Eclipse 4 IDE">
+         <property
+               name="appName"
+               value="Eclipse 4 IDE">
+         </property>
+         <property
+               name="applicationXMI"
+               value="org.eclipse.e4.ide.application/Application.e4xmi">
+         </property>
+         <property
+               name="applicationCSS"
+               value="platform:/plugin/org.eclipse.e4.demo.log/css/default.css">
+         </property>
+         <property
+               name="applicationCSSResources"
+          value="platform:/plugin/org.eclipse.e4.ide.application/images/">
+         </property>
+      </product>
+   </extension>
+   <extension
+         id="id1"
+         point="org.eclipse.e4.workbench.model">
+      <snippet
+            uri="platform:/plugin/org.eclipse.e4.demo.log/xmi/components.e4xmi">
+      </snippet>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/Activator.java b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/Activator.java
new file mode 100644
index 0000000..9e042c8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/Activator.java
@@ -0,0 +1,46 @@
+package org.eclipse.e4.demo.log;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.e4.demo.log"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+	}
+
+	/**
+	 * Returns the shared instance
+	 * 
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/KeyContextView.java b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/KeyContextView.java
new file mode 100644
index 0000000..fe81788
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/KeyContextView.java
@@ -0,0 +1,147 @@
+package org.eclipse.e4.demo.log;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.core.commands.contexts.Context;
+import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.e4.core.contexts.ContextChangeEvent;
+import org.eclipse.e4.core.contexts.IRunAndTrack;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.di.annotations.PostConstruct;
+import org.eclipse.e4.ui.bindings.internal.ContextSet;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.services.IStylingEngine;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+public class KeyContextView {
+	final private Composite parent;
+	private ListViewer myViewer;
+	private ListViewer appViewer;
+	private ContextSet myBindingContextSet = ContextSet.EMPTY;
+	private ContextSet appBindingContextSet = ContextSet.EMPTY;
+
+	/**
+	 * This will not change, and is a good candidate for field injection.
+	 */
+	@Inject
+	private MApplication application;
+
+	/**
+	 * This will not change, and is a good candidate for field injection.
+	 */
+	@Inject
+	private IStylingEngine styler;
+
+	private ContextManager contextManager;
+
+	@Inject
+	public KeyContextView(final Composite parent) {
+		this.parent = new Composite(parent, SWT.NONE);
+		this.parent.setLayout(new GridLayout(2, true));
+	}
+
+	@PostConstruct
+	private void init() {
+		Label label = new Label(parent, SWT.NONE);
+		styler.setClassname(label, "keyContextView");
+		styler.setId(label, "me");
+		label.setText("My Binding Contexts");
+		GridData data = new GridData(SWT.LEFT, SWT.TOP, true, false);
+		label.setLayoutData(data);
+
+		label = new Label(parent, SWT.NONE);
+		styler.setClassname(label, "keyContextView");
+		styler.setId(label, "app");
+		label.setText("Application Binding Contexts");
+		data = new GridData(SWT.LEFT, SWT.TOP, true, false);
+		label.setLayoutData(data);
+
+		myViewer = new ListViewer(parent);
+		data = new GridData(SWT.FILL, SWT.FILL, true, true);
+		myViewer.getControl().setLayoutData(data);
+		myViewer.setContentProvider(ArrayContentProvider.getInstance());
+		LabelProvider labelProvider = new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				if (element instanceof Context) {
+					Context c = (Context) element;
+					return c.getId();
+				}
+				return super.getText(element);
+			}
+		};
+		myViewer.setLabelProvider(labelProvider);
+		myViewer.setInput(myBindingContextSet.getContexts());
+
+		data = new GridData(SWT.FILL, SWT.FILL, true, true);
+		appViewer = new ListViewer(parent);
+		appViewer.getControl().setLayoutData(data);
+		appViewer.setContentProvider(ArrayContentProvider.getInstance());
+		appViewer.setLabelProvider(labelProvider);
+
+		application.getContext().runAndTrack(new IRunAndTrack() {
+			public boolean notify(ContextChangeEvent event) {
+				Set<String> set = (Set<String>) application.getContext().get(
+						IServiceConstants.ACTIVE_CONTEXTS);
+				appBindingContextSet = getContextSet(set);
+				appViewer.setInput(appBindingContextSet.getContexts());
+				return true;
+			}
+		}, null);
+	}
+
+	/**
+	 * This will inject the active contexts, as seen from this view. Because we
+	 * need to take action when this value changes, it is a good candidate for
+	 * method injection.
+	 * 
+	 * @param set
+	 *            active context IDs
+	 */
+	@Inject
+	public void setBindingContextIds(
+			@Named(IServiceConstants.ACTIVE_CONTEXTS) @Optional Set<String> set) {
+		myBindingContextSet = getContextSet(set);
+		if (myViewer != null) {
+			myViewer.setInput(myBindingContextSet.getContexts());
+		}
+	}
+
+	/**
+	 * This is taking advantage of method injection to set a comparator needed
+	 * for this view's correct operation.
+	 * 
+	 * @param manager
+	 *            The context object manager for this application.
+	 */
+	@Inject
+	public void setContextManager(ContextManager manager) {
+		contextManager = manager;
+		if (manager != null && ContextSet.getComparator() == null) {
+			ContextSet.setComparator(new ContextSet.CComp(manager));
+		}
+	}
+
+	private ContextSet getContextSet(Set<String> set) {
+		if (set == null || set.isEmpty() || contextManager == null) {
+			return ContextSet.EMPTY;
+		}
+		ArrayList<Context> contexts = new ArrayList<Context>();
+		for (String id : set) {
+			contexts.add(contextManager.getContext(id));
+		}
+		return new ContextSet(contexts);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/ViewCurrentContextsHandler.java b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/ViewCurrentContextsHandler.java
new file mode 100644
index 0000000..a2e2892
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/ViewCurrentContextsHandler.java
@@ -0,0 +1,16 @@
+package org.eclipse.e4.demo.log;
+
+import java.util.Set;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.services.IServiceConstants;
+
+public class ViewCurrentContextsHandler {
+	public void execute(
+			@Named(IServiceConstants.ACTIVE_CONTEXTS) @Optional Set<String> set) {
+		System.out.println("Active Contexts (unordered):");
+		System.out.println(set);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.log/xmi/components.e4xmi b/examples/org.eclipse.e4.demo.log/xmi/components.e4xmi
new file mode 100644
index 0000000..9868083
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/xmi/components.e4xmi
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:ModelComponents xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu"  xmi:id="_UW9TZfr3Ed6gmo7caOxU9h">
+  <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9q" elementId="component.add.bindingContextView" parentID="org.eclipse.e4.ide.application">
+    <descriptors xmi:id="_2JqwsDEtEd-VhpFUss_l2g" elementId="org.eclipse.e4.demo.log.contextView" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.KeyContextView" label="Binding Context View" category="org.eclipse.e4.secondaryDataStack">
+      <bindingContexts>org.eclipse.e4.ui.contexts.views</bindingContexts>
+    </descriptors>
+    <handlers xmi:id="_8DQrEDK-Ed-ltJ9rgXYhSw" elementId="bindingContexts.display.handler" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.ViewCurrentContextsHandler" command="bindingContexts.display"/>
+    <commands xmi:id="bindingContexts.display" elementId="bindingContexts.display" commandName="Display Current Contexts"/>
+  </components>
+  <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9y" elementId="component.add.bindingContextView.legacy" parentID="org.eclipse.e4.legacy.ide.application">
+    <descriptors xmi:id="_2JqwsDEtEd-VhpFUss_l2g" elementId="org.eclipse.e4.demo.log.contextView" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.KeyContextView" label="Binding Context View" category="org.eclipse.e4.secondaryDataStack">
+      <bindingContexts>org.eclipse.e4.ui.contexts.views</bindingContexts>
+    </descriptors>
+    <handlers xmi:id="_8DQrEDK-Ed-ltJ9rgXYhSw" elementId="bindingContexts.display.handler" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.ViewCurrentContextsHandler" command="bindingContexts.display"/>
+    <commands xmi:id="bindingContexts.display" elementId="bindingContexts.display" commandName="Display Current Contexts"/>
+  </components>
+  <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9l" elementId="component.add.menu.window" parentID="org.eclipse.e4.ide.app.menu.window">
+    <children xsi:type="menu:HandledMenuItem" xmi:id="_UW9TZfr3Ed6gmo7ca1xU9p" elementId="_UW9TZfr3Ed6gmo7ca1xU9p" label="Display Current Contexts" command="bindingContexts.display"/>
+  </components>
+</application:ModelComponents>
diff --git a/examples/org.eclipse.e4.demo.modifier/.classpath b/examples/org.eclipse.e4.demo.modifier/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.modifier/.project b/examples/org.eclipse.e4.demo.modifier/.project
new file mode 100644
index 0000000..02634f4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.modifier</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.modifier/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.modifier/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b6fa1be
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri Mar 13 14:17:49 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.modifier/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.modifier/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9eabb47
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Self modifying demo (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.demo.modifier;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Bundle-Activator: org.eclipse.e4.demo.modifier.Activator
+Bundle-Vendor: Eclipse.org
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.0",
+ org.eclipse.jface;bundle-version="3.5.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.0",
+ org.eclipse.core.databinding;bundle-version="1.2.0",
+ org.eclipse.core.databinding.observable;bundle-version="1.2.0",
+ org.eclipse.jface.databinding;bundle-version="1.3.0",
+ org.mozilla.javascript;bundle-version="1.6.6",
+ org.eclipse.emf.databinding;resolution:=optional,
+ org.eclipse.ui.workbench;resolution:=optional,
+ org.eclipse.ui.forms;resolution:=optional,
+ org.eclipse.core.databinding.property;bundle-version="1.2.0",
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.e4.ui.workbench.swt;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.modifier/build.properties b/examples/org.eclipse.e4.demo.modifier/build.properties
new file mode 100644
index 0000000..fd23492
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               icons/,\
+               modifyWorkbench.product,\
+               xmi/
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/collapseall.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/collapseall.gif
new file mode 100644
index 0000000..a2d80a9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/collapseall.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/pin_view.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/pin_view.gif
new file mode 100644
index 0000000..381c4a9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/pin_view.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif
new file mode 100644
index 0000000..049cac6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/synced.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/synced.gif
new file mode 100644
index 0000000..870934b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/synced.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/trash.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/trash.gif
new file mode 100644
index 0000000..bf961b3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/trash.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/up_nav.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/up_nav.gif
new file mode 100644
index 0000000..884952f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/up_nav.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/copy_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/copy_edit.gif
new file mode 100644
index 0000000..71d7c95
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/copy_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/cut_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/cut_edit.gif
new file mode 100644
index 0000000..d044e59
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/cut_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/delete_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/delete_edit.gif
new file mode 100644
index 0000000..b6922ac
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/delete_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/paste_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/paste_edit.gif
new file mode 100644
index 0000000..39dd4d9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/paste_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/pin_editor.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/pin_editor.gif
new file mode 100644
index 0000000..dfc1dab
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/pin_editor.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/print_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/print_edit.gif
new file mode 100644
index 0000000..04cb84b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/print_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/mviewer.GIF b/examples/org.eclipse.e4.demo.modifier/icons/mviewer.GIF
new file mode 100644
index 0000000..3be38d4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/mviewer.GIF
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/obj16/file_obj.gif b/examples/org.eclipse.e4.demo.modifier/icons/obj16/file_obj.gif
new file mode 100644
index 0000000..7ccc6a7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/obj16/file_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/obj16/fldr_obj.gif b/examples/org.eclipse.e4.demo.modifier/icons/obj16/fldr_obj.gif
new file mode 100644
index 0000000..51e703b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/obj16/fldr_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/obj16/prj_obj.gif b/examples/org.eclipse.e4.demo.modifier/icons/obj16/prj_obj.gif
new file mode 100644
index 0000000..a4ea580
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/obj16/prj_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/modifyWorkbench.product b/examples/org.eclipse.e4.demo.modifier/modifyWorkbench.product
new file mode 100644
index 0000000..7e78d97
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/modifyWorkbench.product
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="Modify Running Workbench" uid="modifyWorkbench" id="org.eclipse.e4.demo.modifier.modifyWorkbench" org.eclipse.e4.ui.model.application="org.eclipse.e4.ui.workbench.swt.application" version="0.9.0" useFeatures="false" includeLaunchers="true">
+
+   <configIni use="default">
+   </configIni>
+
+   <launcherArgs>
+      <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+   </launcherArgs>
+
+   <windowImages/>
+
+   <launcher>
+      <solaris/>
+      <win useIco="false">
+         <bmp/>
+      </win>
+   </launcher>
+
+   <vm>
+   </vm>
+
+   <plugins>
+      <plugin id="com.ibm.icu"/>
+      <plugin id="javax.xml"/>
+      <plugin id="org.apache.xerces"/>
+      <plugin id="org.apache.xml.resolver"/>
+      <plugin id="org.eclipse.core.commands"/>
+      <plugin id="org.eclipse.core.contenttype"/>
+      <plugin id="org.eclipse.core.databinding"/>
+      <plugin id="org.eclipse.core.databinding.observable"/>
+      <plugin id="org.eclipse.core.databinding.property"/>
+      <plugin id="org.eclipse.core.expressions"/>
+      <plugin id="org.eclipse.core.jobs"/>
+      <plugin id="org.eclipse.core.runtime"/>
+      <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
+      <plugin id="org.eclipse.e4.core.services"/>
+      <plugin id="org.eclipse.e4.core.services.annotations"/>
+      <plugin id="org.eclipse.e4.demo.modifier"/>
+      <plugin id="org.eclipse.e4.ui.model.workbench"/>
+      <plugin id="org.eclipse.e4.ui.services"/>
+      <plugin id="org.eclipse.e4.ui.workbench"/>
+      <plugin id="org.eclipse.e4.ui.workbench.renderers.swt"/>
+      <plugin id="org.eclipse.e4.ui.workbench.swt"/>
+      <plugin id="org.eclipse.emf.common"/>
+      <plugin id="org.eclipse.emf.databinding"/>
+      <plugin id="org.eclipse.emf.ecore"/>
+      <plugin id="org.eclipse.emf.ecore.xmi"/>
+      <plugin id="org.eclipse.equinox.app"/>
+      <plugin id="org.eclipse.equinox.common"/>
+      <plugin id="org.eclipse.equinox.concurrent"/>
+      <plugin id="org.eclipse.equinox.preferences"/>
+      <plugin id="org.eclipse.equinox.registry"/>
+      <plugin id="org.eclipse.jface"/>
+      <plugin id="org.eclipse.jface.databinding"/>
+      <plugin id="org.eclipse.osgi"/>
+      <plugin id="org.eclipse.swt"/>
+      <plugin id="org.eclipse.swt.gtk.linux.x86" fragment="true"/>
+      <plugin id="org.eclipse.swt.win32.win32.x86" fragment="true"/>
+      <plugin id="org.mozilla.javascript"/>
+   </plugins>
+
+
+</product>
diff --git a/examples/org.eclipse.e4.demo.modifier/plugin.xml b/examples/org.eclipse.e4.demo.modifier/plugin.xml
new file mode 100644
index 0000000..298cd67
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/plugin.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="modifyWorkbench"
+         point="org.eclipse.core.runtime.products">
+      <product
+            application="org.eclipse.e4.ui.workbench.swt.application"
+            name="Modify Running Workbench">
+         <property
+               name="appName"
+               value="Modify Running Workbench">
+         </property>
+         <property
+               name="applicationXMI"
+               value="/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi">
+         </property>
+      </product>
+   </extension>
+   <extension
+         id="ModelViewer"
+         name="Model Viewer"
+         point="org.eclipse.e4.workbench.model">
+      <model
+            parentID="E4MainWindow"
+            location="xmi/modelViewer.xmi">
+      </model>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            categoryId="org.eclipse.e4.ui.category"
+            defaultHandler="org.eclipse.e4.demo.modifier.ShowUIEditor"
+            id="org.eclipse.e4.demo.modifier.showEditor"
+            name="UI Editor">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            locationURI="menu:org.eclipse.e4.samples">
+         <command
+               commandId="org.eclipse.e4.demo.modifier.showEditor"
+               label="UI Editor"
+               style="push">
+         </command>
+      </menuContribution>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/Activator.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/Activator.java
new file mode 100644
index 0000000..6d53de5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends Plugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.e4.demo.modifier";
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/EMFScriptable.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/EMFScriptable.java
new file mode 100644
index 0000000..9fdbc83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/EMFScriptable.java
@@ -0,0 +1,71 @@
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+public class EMFScriptable extends ScriptableObject {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	private EObject eObject;
+
+	public EMFScriptable(EObject eObject) {
+		this.eObject = eObject;
+	}
+
+	@Override
+	public String getClassName() {
+		return eObject.getClass().getName();
+	}
+
+	private EStructuralFeature findFeature(String name) {
+		for (EStructuralFeature f : eObject.eClass()
+				.getEAllStructuralFeatures()) {
+			if (f.getName().equals(name)) {
+				return f;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public Object get(String arg0, Scriptable arg1) {
+		EStructuralFeature f = findFeature(arg0);
+
+		if (f == null)
+			return super.get(arg0, arg1);
+
+		Object rv = eObject.eGet(f);
+
+		// FIXME java.util.Date, ...
+		if (rv instanceof String || rv instanceof Boolean
+				|| rv instanceof Number) {
+			return rv;
+		} else if (rv instanceof EObject) {
+			return new EMFScriptable(eObject);
+		}
+
+		return super.get(arg0, arg1);
+	}
+
+	@Override
+	public void put(String arg0, Scriptable arg1, Object arg2) {
+		EStructuralFeature f = findFeature(arg0);
+		
+		// We always get a double so we have to convert to the appropriate value
+		if( arg2 instanceof Number ) {
+			if( f.getEType().getInstanceClass() == int.class ) {
+				arg2 = ((Number)arg2).intValue();
+			}
+		}
+		
+		if (f == null)
+			super.put(arg0, arg1, arg2);
+		else
+			eObject.eSet(f, arg2);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ElementView.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ElementView.java
new file mode 100644
index 0000000..b9d70bd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ElementView.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.modifier;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.databinding.observable.Observables;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.value.ComputedValue;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.WritableValue;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ImporterTopLevel;
+import org.mozilla.javascript.ScriptableObject;
+
+public class ElementView {
+	private Realm realm;
+	private IObservableValue selectedElement = null;
+	private IObservableValue jsText;
+	private Text jsInputField;
+	private Context jsContext;
+	private ImporterTopLevel jsScope;
+
+	public ElementView(final Composite parent) {
+		realm = Realm.getDefault();
+		selectedElement = new WritableValue(realm);
+		jsText = new ComputedValue(realm) {
+			@Override
+			protected Object calculate() {
+				return formatJSField((EObject) selectedElement.getValue());
+			}
+		};
+
+		jsInputField = new Text(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
+				| SWT.BORDER);
+
+		Observables.pipe(jsText, SWTObservables.observeText(jsInputField));
+
+		final Button runJSBtn = new Button(parent, SWT.PUSH);
+		runJSBtn.setText("Run Script"); //$NON-NLS-1$
+		runJSBtn.setBounds(10, 320, 100, 25);
+		runJSBtn.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {
+				widgetSelected(e);
+			}
+
+			public void widgetSelected(SelectionEvent e) {
+				runJS(jsInputField.getText());
+			}
+		});
+
+		GridLayoutFactory.fillDefaults().generateLayout(parent);
+		initJS();
+	}
+
+	protected String formatJSField(EObject value) {
+		if (value == null) {
+			return "";
+		}
+		String delim = jsInputField.getLineDelimiter();
+		String jsString = "// " + value.eClass().getName()
+				+ " is selected...\r\n" + "me = selectedElement;" + delim
+				+ "out.println(me);" + delim;
+		for (EStructuralFeature feature : value.eClass()
+				.getEAllStructuralFeatures()) {
+			Object val = value.eGet(feature);
+
+			if (!(val instanceof String) && !(val instanceof Boolean)
+					&& !(val instanceof Number)) {
+				continue;
+			}
+
+			String propName = feature.getName().substring(0, 1).toUpperCase()
+					+ feature.getName().substring(1);
+			propName = feature.getName();
+			String propString;
+
+			if (val instanceof String) {
+				propString = "me." + propName + "=\"" + val + "\"";
+			} else {
+				propString = "me." + propName + "=" + val + "";
+			}
+
+			jsString += propString + delim;
+		}
+
+		return jsString;
+	}
+
+	/**
+	 * TBD this method is not needed; clean it up
+	 * @param selection
+	 */
+	@Inject
+	public void setInput(final EObject selection) {
+		if (selection==null) {
+			return;
+		}
+		realm.asyncExec(new Runnable() {
+			public void run() {
+				selectedElement.setValue(selection);
+			}
+		});
+	}
+
+	/**
+	 * @param selection
+	 */
+	@Inject
+	public void setSelection(final EObject selection) {
+		if (selection==null) {
+			return;
+		}
+		realm.asyncExec(new Runnable() {
+			public void run() {
+				selectedElement.setValue(selection);
+			}
+		});
+	}
+
+	protected void runJS(String jScript) {
+		try {
+			ScriptableObject.putProperty(jsScope, "selectedElement",
+					new EMFScriptable((EObject) selectedElement.getValue()));
+			jsContext.evaluateString(jsScope, jScript,
+					"LCV Evaluator", 0, null); //$NON-NLS-1$
+		} catch (RuntimeException e) {
+			e.printStackTrace();
+			initJS();
+		}
+	}
+
+	private void initJS() {
+		if (jsContext != null)
+			Context.exit();
+
+		jsContext = Context.enter();
+		jsScope = new ImporterTopLevel(jsContext);
+		Object wrappedOut = Context.javaToJS(System.out, jsScope);
+		ScriptableObject.putProperty(jsScope, "out", wrappedOut); //$NON-NLS-1$
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ExitHandler.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ExitHandler.java
new file mode 100755
index 0000000..2f454b4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ExitHandler.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.e4.workbench.ui.IWorkbench;
+
+/**
+ *
+ */
+public class ExitHandler {
+	public void execute(IWorkbench workbench) {
+		workbench.close();
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ModelView.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ModelView.java
new file mode 100644
index 0000000..d1453be
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ModelView.java
@@ -0,0 +1,73 @@
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.Observables;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider;
+import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+public class ModelView {
+	public ModelView(final Composite parent,
+			final IEclipseContext outputContext,
+			final MApplication application) {
+		final Realm realm = Realm.getDefault();
+		TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
+				| SWT.V_SCROLL);
+		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				outputContext.set(IServiceConstants.SELECTION,
+						((StructuredSelection) event.getSelection())
+								.getFirstElement());
+			}
+		});
+		IObservableFactory listFactory = new IObservableFactory() {
+			public IObservable createObservable(Object element) {
+				if (element instanceof EObject
+						&& !((EObject) element).eContents().isEmpty()) {
+					EObject e = (EObject) element;
+					IObservableList observableList = new WritableList(realm);
+					observableList.addAll(e.eContents());
+					return observableList;
+				} else if (element instanceof Object[]) {
+					EObject e = (EObject) ((Object[]) element)[0];
+					IObservableList observableList = new WritableList(realm);
+					observableList.add(e);
+					return observableList;
+				}
+				return Observables.emptyObservableList();
+			}
+		};
+		viewer.setContentProvider(new ObservableListTreeContentProvider(
+				listFactory, new TreeStructureAdvisor() {
+					public Boolean hasChildren(Object element) {
+						return Boolean.valueOf(element instanceof EObject);
+					}
+				}));
+		viewer.setLabelProvider(new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				if (element instanceof EObject) {
+					return ((EObject) element).eClass().getName();
+				}
+				return super.getText(element);
+			}
+		});
+		viewer.setInput(new Object[] { application });
+		GridLayoutFactory.fillDefaults().generateLayout(parent);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/SampleView.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/SampleView.java
new file mode 100755
index 0000000..3f6bce3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/SampleView.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ */
+public class SampleView {
+	/**
+	 * Create the sample view.
+	 * 
+	 * @param parent
+	 * @param selectionService
+	 */
+	public SampleView(Composite parent, final IEclipseContext outputContext,
+			final IExtensionRegistry registry) {
+		TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
+				| SWT.V_SCROLL);
+		viewer.getTree().setData("class", "navigator"); //$NON-NLS-1$ //$NON-NLS-2$
+		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				outputContext.set(IServiceConstants.SELECTION, event.getSelection());
+			}
+		});
+		viewer.setContentProvider(new ITreeContentProvider() {
+
+			public Object[] getChildren(Object parentElement) {
+				if (parentElement instanceof IConfigurationElement) {
+					return ((IConfigurationElement) parentElement)
+							.getChildren();
+				}
+				return null;
+			}
+
+			public Object getParent(Object element) {
+				if (element instanceof IConfigurationElement) {
+					return ((IConfigurationElement) element).getParent();
+				}
+				return null;
+			}
+
+			public boolean hasChildren(Object element) {
+				if (element instanceof IConfigurationElement) {
+					return ((IConfigurationElement) element).getChildren().length > 0;
+				}
+				return false;
+			}
+
+			public Object[] getElements(Object inputElement) {
+				if (inputElement instanceof IExtension) {
+					return ((IExtension) inputElement)
+							.getConfigurationElements();
+				}
+				return null;
+			}
+
+			public void dispose() {
+			}
+
+			public void inputChanged(Viewer viewer, Object oldInput,
+					Object newInput) {
+			}
+		});
+		viewer.setLabelProvider(new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				if (element instanceof IConfigurationElement) {
+					IConfigurationElement c = (IConfigurationElement) element;
+					String tag = c.getName();
+					String id = c.getAttribute("id"); //$NON-NLS-1$
+					if (id == null) {
+						id = c.getAttribute("name"); //$NON-NLS-1$
+					}
+					if (id == null) {
+						id = c.getAttribute("api"); //$NON-NLS-1$
+					}
+					if (id == null) {
+						id = c.getAttribute("class"); //$NON-NLS-1$
+					}
+					return tag + "(" + id + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+				}
+				return ""; //$NON-NLS-1$
+			}
+
+			@Override
+			public Image getImage(Object element) {
+				// TODO update this to look for an icon or image attribute
+				return super.getImage(element);
+			}
+		});
+
+		IExtension input = null;
+		IExtension[] extensions = registry
+				.getExtensions("org.eclipse.e4.ui.workbench"); //$NON-NLS-1$
+		for (int i = 0; i < extensions.length; i++) {
+			if (extensions[i].getExtensionPointUniqueIdentifier().equals(
+					"org.eclipse.e4.services")) { //$NON-NLS-1$
+				input = extensions[i];
+				break;
+			}
+		}
+		viewer.setInput(input);
+		GridLayoutFactory.fillDefaults().generateLayout(parent);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ShowUIEditor.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ShowUIEditor.java
new file mode 100644
index 0000000..0aa2c7d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ShowUIEditor.java
@@ -0,0 +1,38 @@
+package org.eclipse.e4.demo.modifier;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.e4.demo.viewer.ModelUtils;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+
+public class ShowUIEditor extends AbstractHandler {
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		MApplication model = (MApplication) HandlerUtil.getVariable(event, MApplication.class.getName());
+		Shell curWindow = (Shell) model.getContext().get(IServiceConstants.ACTIVE_SHELL);
+		if (curWindow == null)
+			return null;
+		
+		MWindow winPart = (MWindow) curWindow.getData(AbstractPartRenderer.OWNING_ME);
+		MPart uiEditor = ModelUtils.findPart(winPart, "UI Editor");
+		if (uiEditor.isVisible()) {
+			Shell editorShell = (Shell) uiEditor.getWidget();
+			if(editorShell == null) {
+				uiEditor.setVisible(false);
+			}
+			else {
+				if (!editorShell.isDisposed())
+					return null;
+			}
+		}
+		uiEditor.setVisible(true);
+		return null;
+	}
+	
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ImageManagerHelper.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ImageManagerHelper.java
new file mode 100644
index 0000000..4102fb3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ImageManagerHelper.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MGenericTile;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Helps manage resources.
+ */
+public class ImageManagerHelper {
+
+	static final public int IMAGE_WORKBENCH_WINDOW = 1;
+	static final public int IMAGE_SASH = 2;
+	static final public int IMAGE_STACK = 3;
+
+	static final private String IMAGE_PATH = "platform:/plugin/org.eclipse.e4.demo.modifier/icons/obj16/";
+
+	private ImageRegistry imageRegistry;
+
+	public ImageManagerHelper() {
+		imageRegistry = new ImageRegistry();
+	}
+
+	public Image getImage(String path) {
+		if (path == null || path.length() == 0)
+			return null;
+		
+		Image image = imageRegistry.get(path);
+		if (image != null)
+			return image;
+		URL url;
+		try {
+			url = new URL(path);
+		} catch (MalformedURLException e) {
+			e.printStackTrace(); // report and continue
+			return null;
+		}
+		ImageDescriptor desc = ImageDescriptor.createFromURL(url);
+		image = desc.createImage();
+		if (image != null)
+			imageRegistry.put(path, image);
+		return image;
+	}
+
+	public Image getImage(int id) {
+		String registryID = Integer.toString(id);
+		Image image = imageRegistry.get(registryID);
+		if (image != null)
+			return image;
+		URL url = createURL(id);
+		ImageDescriptor desc = ImageDescriptor.createFromURL(url);
+		image = desc.createImage();
+		if (image != null)
+			imageRegistry.put(registryID, image);
+		return image;
+	}
+
+	private URL createURL(int id) {
+		String result = null;
+		switch (id) {
+		case IMAGE_WORKBENCH_WINDOW: // ISharedImages.IMG_OBJ_PROJECT
+			result = IMAGE_PATH + "prj_obj.gif";
+			break;
+		case IMAGE_SASH: // ISharedImages.IMG_OBJ_FOLDER
+			result = IMAGE_PATH + "fldr_obj.gif";
+			break;
+		case IMAGE_STACK: // ISharedImages.IMG_OBJ_FILE
+			result = IMAGE_PATH + "file_obj.gif";
+			break;
+		default:
+		}
+		try {
+			return new URL(result);
+		} catch (MalformedURLException e) {
+			e.printStackTrace(); // report and continue
+			return null;
+		}
+	}
+
+	public void dispose() {
+		imageRegistry.dispose();
+	}
+
+	public Image getElementImage(Object element) {
+		if (element instanceof MWindow)
+			return getElementImage(ImageManagerHelper.IMAGE_WORKBENCH_WINDOW);
+		else if (element instanceof MGenericTile<?>)
+			return getElementImage(ImageManagerHelper.IMAGE_SASH);
+		else if (element instanceof MElementContainer<?>)
+			return getImage(ImageManagerHelper.IMAGE_STACK);
+        return null;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelExplorer.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelExplorer.java
new file mode 100644
index 0000000..1ee20b6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelExplorer.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import java.util.Iterator;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.MItem;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPartSashContainer;
+import org.eclipse.e4.ui.model.application.MPartStack;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Tree displaying contents of the E4 model.
+ */
+public class ModelExplorer {
+	
+	private IEclipseContext context;
+	private TreeViewer viewer;
+	
+	MApplicationElement rootElement;
+	
+	private ImageManagerHelper imageHelper;
+	
+	private DragSourceListener dragListener = new DragSourceListener() {
+		public void dragFinished(DragSourceEvent event) {
+		}
+		public void dragSetData(DragSourceEvent event) {
+//			IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+//			System.out.println("count: " + selection.size());
+		}
+		public void dragStart(DragSourceEvent event) {
+			IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+			if (selection.size() != 1) {
+				event.doit = false;
+			}
+			else {
+				event.doit = selection.getFirstElement() instanceof MPart; 
+			}
+		}
+	};
+
+	private DropTargetListener dropListener = new DropTargetListener() {
+		public void dragEnter(DropTargetEvent event) {
+		}
+		public void dragOver(DropTargetEvent event) {
+			event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL
+					| DND.FEEDBACK_EXPAND;
+
+			Widget curItem = event.item;
+			if (curItem != null) {
+				Object curElement = curItem.getData();
+				if (curElement instanceof MPartStack) {
+					event.detail = DND.DROP_MOVE;
+				}
+				else {
+					event.detail = DND.DROP_NONE;
+				}
+			}
+		}
+		
+		public void dragOperationChanged(DropTargetEvent event) {
+			if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) {
+				if (event.detail != DND.DROP_COPY
+					&& event.detail != DND.DROP_MOVE) {
+					event.detail = DND.DROP_NONE;
+				}
+			}
+		}
+
+		public void drop(DropTargetEvent event) {
+			if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) {
+				MPartStack sm = (MPartStack) event.item.getData();
+				IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+				MPart view = (MPart) selection.getFirstElement();
+				sm.getChildren().add(view);
+				ModelUtils.activate(view);
+				viewer.refresh();
+			}
+		}
+		public void dragLeave(DropTargetEvent event) {
+		}
+		public void dropAccept(DropTargetEvent event) {
+		}
+	};
+	
+	private ITreeContentProvider contentProvider = new ITreeContentProvider() {	
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+		
+		public void dispose() {
+		}
+
+		public Object[] getChildren(Object parentElement) {
+			return null;
+		}
+
+		public Object getParent(Object element) {
+			return null;
+		}
+
+		public boolean hasChildren(Object element) {
+			return false;
+		}
+
+		public Object[] getElements(Object inputElement) {
+			return null;
+		}
+	};
+	 
+	class ViewLabelProvider implements ILabelProvider {
+
+		public Image getImage(Object element) {
+			if (element instanceof MItem) {
+				String iconPath = ((MItem) element).getIconURI();
+				return imageHelper.getImage(iconPath);
+			}
+	
+			return imageHelper.getElementImage(element);
+		}
+
+		public String getText(Object element) {
+			if (element instanceof MItem)
+				return ((MItem)element).getName();
+			if (element instanceof MPartStack)
+				return "Stack: \"" + ((MPartStack) element).getId() + "\"";
+			if (element instanceof MPartSashContainer)
+				return "Sash: \"" + ((MPartSashContainer) element).getId() + "\"";
+			if (element instanceof MPerspective)
+				return "Perspective \"" + ((MPerspective) element).getId() + "\""; 
+			if (element instanceof MWindow)
+				return "Workbench Window"; 
+			return element.getClass().getSimpleName();
+		}
+
+		public void addListener(ILabelProviderListener listener) {
+		}
+
+		public void dispose() {
+		}
+
+		public boolean isLabelProperty(Object element, String property) {
+			return false;
+		}
+
+		public void removeListener(ILabelProviderListener listener) {
+		}
+	}
+
+	public ModelExplorer(Composite parent) {
+		imageHelper = new ImageManagerHelper();
+		
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		composite.setLayout(layout);
+		GridData data = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
+		composite.setLayoutData(data);
+		
+		// add some space around the label
+		Label label = new Label(composite, SWT.NONE);
+		label.setText("&E4 Model");
+		GridData dataLabel = new GridData();
+		dataLabel.horizontalIndent = 5;
+		dataLabel.verticalIndent = 5;
+		
+		viewer = new TreeViewer(composite);
+		viewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		viewer.setContentProvider(contentProvider);
+		viewer.setLabelProvider(new ViewLabelProvider());
+		
+		viewer.getControl().setData("viewpart", this);
+		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				handleSelection(event);
+			}
+		});
+		
+		// Add DnD support
+		int ops = DND.DROP_COPY | DND.DROP_MOVE; 
+		Transfer[] xFers = { LocalSelectionTransfer.getTransfer() };
+		viewer.addDragSupport(ops, xFers, dragListener);
+		viewer.addDropSupport(ops, xFers, dropListener);
+		
+		// TBD this really need to be replaced by an API 
+		// static MApplication getApplication() 
+		// on something
+		MUIElement element = ModelUtils.getElement(parent);
+		EObject topObject = ModelUtils.topObject(element);
+		viewer.setInput(topObject);
+		
+		// double-clicks activate the selected part
+		viewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				TreeSelection selection = (TreeSelection) event.getSelection();
+				MPart selected = (MPart) selection.getFirstElement();
+				// TBD there should be an API to activate MPart 
+				ModelUtils.activate(selected);
+			}});
+		GridLayoutFactory.fillDefaults().generateLayout(parent);
+	}
+	
+	protected void handleSelection(SelectionChangedEvent event) {
+		if (event.getSelection() instanceof IStructuredSelection) {
+			IStructuredSelection sel = (IStructuredSelection) event.getSelection();
+			Object selObj = sel.getFirstElement();
+			if (selObj instanceof EObject)
+				context.modify(IServiceConstants.SELECTION, selObj);
+		}
+	}
+
+	public String[] getPropIds(EObject selObj) {
+		if (selObj == null)
+			return new String[0];
+		
+		EList<EStructuralFeature> features = selObj.eClass().getEAllStructuralFeatures();
+		String[] ids = new String[features.size()];
+		int count = 0;
+		for (Iterator iterator = features.iterator(); iterator.hasNext();) {
+			EStructuralFeature structuralFeature = (EStructuralFeature) iterator
+					.next();
+			String featureName = structuralFeature.getName();
+			ids[count++] = featureName;
+		}
+		
+		return ids;
+	}
+	
+	public Object getProperty(EObject eObj, String id) {
+		if (eObj == null)
+			return null;
+		
+	    EStructuralFeature eFeature = eObj.eClass().getEStructuralFeature(id);
+	    if (eFeature == null)
+	    	return null;
+	    
+		return eObj.eGet(eFeature);
+	}
+	
+	public void dispose() {
+		// TBD any cleanup?
+	}
+	
+	public void contextSet(IEclipseContext context) {
+		this.context = context;
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelUtils.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelUtils.java
new file mode 100644
index 0000000..f251bce
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelUtils.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import java.util.Iterator;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.contexts.IContextConstants;
+import org.eclipse.e4.ui.model.application.MContext;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Pieces of code that really should be available as APIs somewhere.
+ */
+public class ModelUtils {
+
+	/**
+	 * Return a parent context for this part.
+	 * 
+	 * @param part
+	 *            the part to start searching from
+	 * @return the parent's closest context, or global context if none in the
+	 *         hierarchy
+	 */
+	public static IEclipseContext getContextForParent(MUIElement part) {
+		MContext pwc = getParentWithContext(part);
+		return pwc != null ? pwc.getContext() : null;
+	}
+
+	/**
+	 * Return a parent context for this part.
+	 * 
+	 * @param part
+	 *            the part to start searching from
+	 * @return the parent's closest context, or global context if none in the
+	 *         hierarchy
+	 */
+	public static MContext getParentWithContext(MUIElement part) {
+		MElementContainer<MUIElement> parent = part.getParent();
+		while (parent != null) {
+			if (parent instanceof MContext) {
+				if (((MContext) parent).getContext() != null)
+					return (MContext) parent;
+			}
+			parent = parent.getParent();
+		}
+		return null;
+	}
+
+	/**
+	 * Return a context for this part.
+	 * 
+	 * @param element
+	 *            the part to start searching from
+	 * @return the closest context, or global context if none in the hierarchy
+	 */
+	public static IEclipseContext getContext(MUIElement element) {
+		if (element instanceof MContext) {
+			IEclipseContext theContext = ((MContext) element).getContext();
+			if (theContext != null)
+				return theContext;
+		}
+		return getContextForParent(element);
+	}
+	
+	/**
+	 * Activate the part in the hierarchy. This should either still be internal
+	 * or be a public method somewhere else.
+	 * 
+	 * @param element
+	 */
+	public static void activate(MUIElement element) {
+		IEclipseContext curContext = getContext(element);
+		MUIElement curElement = element;
+		MContext pwc = getParentWithContext(element);
+		while (pwc != null) {
+			IEclipseContext parentContext = pwc.getContext();
+			if (parentContext != null) {
+				parentContext.set(IContextConstants.ACTIVE_CHILD, curContext);
+				curContext = parentContext;
+			}
+
+			// Ensure that the UI model has the part 'on top'
+			while (curElement != pwc) {
+				MElementContainer<MUIElement> parent = curElement.getParent();
+				if (parent.getActiveChild() != element)
+					parent.setActiveChild(curElement);
+				curElement = parent;
+			}
+
+			pwc = getParentWithContext((MUIElement) pwc);
+		}
+	}
+	
+	/**
+	 * Get model element associated with the composite or
+	 * its containers.
+	 * This method may return null.
+	 */
+	static MUIElement getElement(Composite composite) {
+		for (Composite container = composite; container != null; container = container.getParent()) {
+			Object owner = container.getData(AbstractPartRenderer.OWNING_ME);
+			if (owner == null)
+				continue;
+			if (owner instanceof MUIElement)
+				return (MUIElement) owner;
+		}
+		return null;
+	}
+	
+	/**
+	 * Get context associated with the composite or its containers.
+	 * This method may return null.
+	 */
+	static IEclipseContext getContext(Composite composite) {
+		MUIElement element = getElement(composite);
+		return getContext(element);
+	}
+	
+	/**
+	 * Returns a model root for a model tree element.
+	 */
+	static public EObject topObject(MUIElement part) {
+		MUIElement lastTop = part;
+		MUIElement currentTop = part.getParent();
+		while (currentTop != null) {
+			lastTop = currentTop;
+			currentTop = currentTop.getParent();
+		}
+		return ((EObject) lastTop).eContainer(); // MWindow -> MApp 
+	}
+
+	private static MUIElement findElementById(MUIElement element, String id) {
+		if (id == null || id.length() == 0)
+			return null;
+
+		// is it me?
+		if (id.equals(element.getId()))
+			return element;
+
+		// Recurse
+		if (element instanceof MElementContainer<?>) {
+			MUIElement foundPart = null;
+			EList<MUIElement> children = ((MElementContainer<MUIElement>) element).getChildren();
+			for (MUIElement childPart : children) {
+				foundPart = findElementById(childPart, id);
+				if (foundPart != null)
+					return foundPart;
+			}
+		}
+
+		return null;
+	}
+
+	public static MPart findPart(MUIElement toSearch, String id) {
+		MPart found = (MPart) findElementById(toSearch, id);
+		if (found instanceof MPart)
+			return (MPart) found;
+
+		return null;
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesElement.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesElement.java
new file mode 100644
index 0000000..07a5527
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesElement.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.databinding.EMFObservables;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * Basic control for model items 
+ */
+public class PropertiesElement extends Composite {
+	
+	protected EObject selectedObject;
+
+	protected DataBindingContext dbc;
+	
+	private Text id;
+	private Binding idBinding;
+	
+	protected FormToolkit toolkit;
+	protected ScrolledForm form;
+	protected Section right;
+	
+	protected Composite comp;
+
+	public PropertiesElement(final Composite parent) {
+		super(parent, SWT.NONE);
+		
+		toolkit = new FormToolkit(parent.getDisplay());
+		form = toolkit.createScrolledForm(this);
+		form.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+		form.getBody().setLayout(new GridLayout());
+		
+		right = toolkit.createSection(form.getBody(), Section.TITLE_BAR
+				| Section.EXPANDED);
+		right.setText("Properties");
+		right.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL));
+
+		comp = toolkit.createComposite(right);
+		comp.setLayout(new GridLayout(2, false));
+		comp.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+		right.setClient(comp);
+
+		dbc = new DataBindingContext();
+		
+		id = createTextControl(comp, "&ID:", SWT.NONE);
+		
+		GridLayoutFactory.fillDefaults().generateLayout(this);
+	}
+	
+	/**
+	 * Passing the focus request to the form.
+	 */
+	public boolean setFocus() {
+		boolean result = super.setFocus();
+		form.setFocus();
+		return result;
+	}
+
+	protected Text createTextControl(Composite parent, String labelText, int style) {
+		
+		Label label = toolkit.createLabel(parent, labelText);
+		label.setLayoutData(new GridData());
+		Text result = toolkit.createText(parent, "", style);
+		result.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
+		return result;
+	}
+	
+	protected Button createButton(Composite parent, String labelText, int style) {
+		Button result = toolkit.createButton(parent, labelText, SWT.CHECK | style);
+		return result;
+	}
+	
+	protected Binding bind(Text text, EStructuralFeature feature) {
+		if (selectedObject == null)
+			return null;
+		IObservableValue observable = EMFObservables.observeValue(selectedObject, feature);
+		return dbc.bindValue(SWTObservables.observeText(text, SWT.Modify), observable, null, null);
+	}
+
+	protected Binding bind(Button button, EStructuralFeature feature) {
+		if (selectedObject == null)
+			return null;
+		IObservableValue observable = EMFObservables.observeValue(selectedObject, feature);
+		return dbc.bindValue(SWTObservables.observeSelection(button), observable, null, null);
+	}
+	
+	public void selected(EObject selected) {
+		if (selected == selectedObject)
+			return;
+		clearBindings();
+		selectedObject = selected;
+		
+		idBinding = bind(id, MApplicationPackage.Literals.APPLICATION_ELEMENT__ID);
+	}
+	
+	protected void clearBindings() {
+		if (idBinding != null) {
+			idBinding.dispose();
+			idBinding = null;
+		}
+	}
+	
+	public void dispose() {
+		clearBindings();
+		toolkit.dispose();
+	}
+	
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesPart.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesPart.java
new file mode 100644
index 0000000..a350061
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesPart.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Basic information for the MContributedPart 
+ */
+public class PropertiesPart extends PropertiesElement {
+	
+	private Text name;
+	private Binding nameBinding;
+	private Text tooltip;
+	private Binding tooltipBinding;
+	private Text icon;
+	private Binding iconBinding;
+	private Button visible;
+	private Binding visibleBinding;
+	
+	public PropertiesPart(final Composite parent) {
+		super(parent);
+
+		name = createTextControl(comp, "&Name:", SWT.NONE);
+		tooltip = createTextControl(comp, "&Tootip:", SWT.NONE);
+		icon = createTextControl(comp, "Icon &URI:", SWT.NONE);
+
+		visible = createButton(comp, "&Visible", SWT.NONE);
+		GridData checkboxData = new GridData(SWT.RIGHT, SWT.TOP, false, false, 2, 1);
+		visible.setLayoutData(checkboxData);
+	}
+
+	public void selected(EObject selected) {
+		super.selected(selected);
+		
+		nameBinding = bind(name, MApplicationPackage.Literals.UI_ITEM__NAME);
+		tooltipBinding = bind(tooltip, MApplicationPackage.Literals.UI_ITEM__TOOLTIP);
+		iconBinding = bind(icon, MApplicationPackage.Literals.UI_ITEM__ICON_URI);
+		visibleBinding = bind(visible, MApplicationPackage.Literals.UI_ELEMENT__VISIBLE);
+	}
+	
+	protected void clearBindings() {
+		super.clearBindings();
+
+		if (nameBinding != null) {
+			nameBinding.dispose();
+			nameBinding = null;
+		}
+		if (tooltipBinding != null) {
+			tooltipBinding.dispose();
+			tooltipBinding = null;
+		}
+		if (iconBinding != null) {
+			iconBinding.dispose();
+			iconBinding = null;
+		}
+		if (visibleBinding != null) {
+			visibleBinding.dispose();
+			visibleBinding = null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesSash.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesSash.java
new file mode 100644
index 0000000..d5ef01f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesSash.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.databinding.EMFObservables;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Basic information for the MStack 
+ */
+public class PropertiesSash extends PropertiesElement {
+	
+	private Text policy;
+	private Text weights;
+	private Binding weightsBinding;
+	private Button visible;
+	private Binding visibleBinding;
+	
+	public PropertiesSash(final Composite parent) {
+		super(parent);
+		policy = createTextControl(comp, "&Policy:", SWT.READ_ONLY);
+		weights = createTextControl(comp, "&Weights:", SWT.NONE);
+		visible = createButton(comp, "&Visible", SWT.NONE);
+		GridData checkboxData = new GridData(SWT.RIGHT, SWT.TOP, false, false, 2, 1);
+		visible.setLayoutData(checkboxData);
+	}
+
+	public void selected(EObject selected) {
+		super.selected(selected);
+		weightsBinding = bindList(weights, MApplicationPackage.Literals.GENERIC_TILE__WEIGHTS);
+		visibleBinding = bind(visible, MApplicationPackage.Literals.UI_ELEMENT__VISIBLE);
+	}
+	
+	protected Binding bindList(Text text, EStructuralFeature feature) {
+		IObservableValue observable = EMFObservables.observeValue(selectedObject, feature);
+		// NOTE: Do not use SWT.Modify as it might cause StackOverflow
+		// when stack is dragged
+		return dbc.bindValue(SWTObservables.observeText(text, SWT.FocusOut), observable,
+				new UpdateValueStrategy () { // Text to EMF model
+					@Override
+					public Object convert(Object value) {
+						if (!(value instanceof String))
+							return super.convert(value);
+						
+						String[] parts = ((String) value).split(", ");
+						EList<Integer> emfList = new BasicEList<Integer>(parts.length); 
+						for(String part : parts) {
+							try {
+								emfList.add(Integer.decode(part));
+							} catch (NumberFormatException e) {
+								// can't process; pass to superclass
+								return super.convert(value);
+							}
+						}
+						return emfList;
+					}
+				},
+				new UpdateValueStrategy () { // EMF model to Text
+					@Override
+					public Object convert(Object value) {
+						if (!(value instanceof EList<?>))
+							return super.convert(value);
+						StringBuffer result = new StringBuffer();
+						for(Object element : (EList<?>) value) {
+							if (result.length() != 0)
+								result.append(", ");
+							result.append(element.toString());
+						}
+						return result.toString();
+					}
+				});
+	}
+	
+	
+	protected void clearBindings() {
+		super.clearBindings();
+		if (weightsBinding != null) {
+			weightsBinding.dispose();
+			weightsBinding = null;
+		}
+		if (visibleBinding != null) {
+			visibleBinding.dispose();
+			visibleBinding = null;
+		}
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesStack.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesStack.java
new file mode 100644
index 0000000..e3e2037
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesStack.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Basic information for the MStack 
+ */
+public class PropertiesStack extends PropertiesElement {
+	
+	private Text policy;
+	private Button visible;
+	private Binding visibleBinding;
+	
+	public PropertiesStack(final Composite parent) {
+		super(parent);
+		visible = createButton(comp, "&Visible", SWT.NONE);
+		GridData checkboxData = new GridData(SWT.RIGHT, SWT.TOP, false, false, 2, 1);
+		visible.setLayoutData(checkboxData);
+	}
+
+	public void selected(EObject selected) {
+		super.selected(selected);
+		visibleBinding = bind(visible, MApplicationPackage.Literals.UI_ELEMENT__VISIBLE);
+	}
+	
+	protected void clearBindings() {
+		super.clearBindings();
+		if (visibleBinding != null) {
+			visibleBinding.dispose();
+			visibleBinding = null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabAdvanced.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabAdvanced.java
new file mode 100644
index 0000000..288370d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabAdvanced.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import java.util.Iterator;
+
+import javax.inject.Inject;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ComboBoxCellEditor;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+
+public class TabAdvanced {
+	static private final String[] booleanValues = new String[] { "true", "false" };
+	
+	private TableViewer tableViewer;
+
+	private class EObjectFeature {
+		public EObject eObj;
+		public EStructuralFeature feature;
+
+		public EObjectFeature(EObject eObj, EStructuralFeature feature) {
+			this.eObj = eObj;
+			this.feature = feature;
+		}
+	}
+
+	private class PropertiesEditingSupport extends EditingSupport {
+
+		private CellEditor textEditor;
+		private ComboBoxCellEditor booleanEditor;
+
+		public PropertiesEditingSupport(ColumnViewer viewer) {
+			super(viewer);
+			textEditor = new TextCellEditor(((TableViewer) viewer).getTable());
+			booleanEditor = new ComboBoxCellEditor(((TableViewer) viewer)
+					.getTable(), booleanValues, SWT.READ_ONLY) {
+				@Override
+				public boolean isActivated() {
+					return true;
+				}
+			};
+		}
+
+		@Override
+		protected boolean canEdit(Object element) {
+			Class<?> clazz = ((EObjectFeature) element).feature.getEType().getInstanceClass();
+			String clsStr = clazz.getName();
+			if (clsStr.equals("java.lang.String"))
+				return true;
+			if (clsStr.equals("boolean"))
+				return true;
+			return false;
+		}
+
+		@Override
+		protected CellEditor getCellEditor(Object element) {
+			if (isBoolean((EObjectFeature) element))
+				return booleanEditor;
+			else
+				return textEditor;
+		}
+
+		@Override
+		protected Object getValue(Object element) {
+			Object result = getPropertyValue((EObjectFeature) element);
+			if (isBoolean((EObjectFeature) element)) {
+				if (result.equals("true"))
+					return new Integer(0);
+				else
+					return new Integer(1);
+			}
+			return result;
+		}
+
+		@Override
+		protected void setValue(Object element, Object value) {
+			EObjectFeature dataObject = (EObjectFeature) element;
+			if (isBoolean(dataObject)) {
+				// NOTE: Workaround for the order of events:
+				// combo box first closes, then updates its selection 
+				CCombo combo = (CCombo) booleanEditor.getControl();
+				int selection = combo.getSelectionIndex();
+				value = new Boolean(selection == 0);
+			}
+			dataObject.eObj.eSet(dataObject.feature, value);
+			// this is probably not the most efficient way, but it works:
+			tableViewer.refresh(true);
+		}
+	}
+
+	public TabAdvanced(final Composite parent) {
+		Table table = new Table(parent, SWT.NONE | SWT.FULL_SELECTION);
+		table.setLayoutData(new GridData(GridData.FILL_BOTH
+				| GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+		tableViewer = new TableViewer(table);
+		TableViewerColumn columnName = new TableViewerColumn(tableViewer,
+				SWT.NONE);
+		columnName.getColumn().setText("Property");
+		columnName.getColumn().setResizable(true);
+
+		TableViewerColumn columnValue = new TableViewerColumn(tableViewer,
+				SWT.NONE);
+		columnValue.getColumn().setText("Value");
+		columnValue.getColumn().setResizable(true);
+
+		columnValue
+				.setEditingSupport(new PropertiesEditingSupport(tableViewer));
+
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+
+		TableLayout layoutLayout = new TableLayout();
+		layoutLayout.addColumnData(new ColumnWeightData(1));
+		layoutLayout.addColumnData(new ColumnWeightData(2));
+		table.setLayout(layoutLayout);
+
+		tableViewer.setContentProvider(new IStructuredContentProvider() {
+
+			private EObject eObj;
+
+			public void dispose() {
+				// TODO Auto-generated method stub
+			}
+
+			public void inputChanged(Viewer viewer, Object oldInput,
+					Object newInput) {
+				eObj = (EObject) newInput;
+			}
+
+			public Object[] getElements(Object inputElement) {
+				EList<EStructuralFeature> features = eObj.eClass()
+						.getEAllStructuralFeatures();
+				EObjectFeature[] result = new EObjectFeature[features.size()];
+				int pos = 0;
+				for (Iterator<?> iterator = features.iterator(); iterator
+						.hasNext();) {
+					EStructuralFeature feature = (EStructuralFeature) iterator
+							.next();
+					result[pos] = new EObjectFeature(eObj, feature);
+					pos++;
+				}
+				return result;
+			}
+		});
+
+		tableViewer.setLabelProvider(new ITableLabelProvider() {
+
+			public Image getColumnImage(Object element, int columnIndex) {
+				return null;
+			}
+
+			public String getColumnText(Object element, int columnIndex) {
+				switch (columnIndex) {
+				case 0:
+					return ((EObjectFeature) element).feature.getName();
+				case 1:
+					return getPropertyValue((EObjectFeature) element);
+				}
+				return null;
+			}
+
+			public void addListener(ILabelProviderListener listener) {
+			}
+
+			public void dispose() {
+			}
+
+			public boolean isLabelProperty(Object element, String property) {
+				return false;
+			}
+
+			public void removeListener(ILabelProviderListener listener) {
+			}
+		});
+		GridLayoutFactory.fillDefaults().generateLayout(parent);
+	}
+
+	private Object getProperty(EObject eObj, String id) {
+		if (eObj == null)
+			return null;
+
+		EStructuralFeature eFeature = eObj.eClass().getEStructuralFeature(id);
+		if (eFeature == null)
+			return null;
+		return eObj.eGet(eFeature);
+	}
+
+	@Inject
+	public void setSelection(final EObject selection) {
+		if (selection == null)
+			return;
+		tableViewer.setInput(selection);
+	}
+
+	private String getPropertyValue(EObjectFeature eDataObj) {
+		Class<?> clazz = eDataObj.feature.getEType().getInstanceClass();
+		String clsStr = clazz.getName();
+		Object propVal = getProperty(eDataObj.eObj, eDataObj.feature.getName());
+
+		if (clsStr.equals("java.lang.String") || clsStr.equals("int")) {
+			if (propVal == null)
+				return "<null> ";
+			else
+				return propVal.toString();
+		} else if (clsStr.equals("boolean")) {
+			if (propVal == null)
+				return "<null> ";
+			else
+				return propVal.toString();
+		}
+
+		if (propVal == null)
+			return "<null> ";
+		else
+			return propVal.getClass().getName();
+	}
+
+	private boolean isBoolean(EObjectFeature eDataObj) {
+		Class<?> clazz = eDataObj.feature.getEType().getInstanceClass();
+		String clsStr = clazz.getName();
+		return clsStr.equals("boolean");
+	}
+
+	public void dispose() {
+		// TBD any cleanup?
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabBasic.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabBasic.java
new file mode 100644
index 0000000..71598d0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabBasic.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.viewer;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPartSashContainer;
+import org.eclipse.e4.ui.model.application.MPartStack;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+// TBD contents of this control is an MStack
+
+public class TabBasic {
+	
+	private EObject selectedObject;
+    private StackLayout stackLayout;
+	private Composite comp;
+    
+    // Pre-made composites for common element types
+    private PropertiesElement elementProperties;
+    private PropertiesElement contribItemProperties;
+    private PropertiesElement stackProperties;
+    private PropertiesElement sashProperties;
+	private Composite noSelection;
+	
+	public TabBasic(final Composite parent) {
+		comp = new Composite(parent, SWT.NONE);
+		comp.setLayout(new GridLayout());
+		comp.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+        stackLayout = new StackLayout();
+        stackLayout.marginHeight = 0;
+        stackLayout.marginWidth = 0;
+        comp.setLayout(stackLayout);
+        
+        noSelection = new Composite(comp, SWT.NONE);
+        noSelection.setLayout(new FillLayout());
+		new Label(noSelection, SWT.NONE).setText("No selection");
+        
+        stackLayout.topControl = noSelection;
+        
+        elementProperties = new PropertiesElement(comp);
+		contribItemProperties = new PropertiesPart(comp);
+		stackProperties = new PropertiesStack(comp);
+		sashProperties = new PropertiesSash(comp);
+		GridLayoutFactory.fillDefaults().generateLayout(parent);
+	}
+	
+	@Inject
+	public void setSelection(final EObject selected) {
+		if (selected == null)
+			return;
+		if (selected == selectedObject)
+			return;
+		selectedObject = selected;
+		
+		if (selectedObject instanceof MPartStack) {
+			stackLayout.topControl = stackProperties;
+			stackProperties.selected(selectedObject);
+		} else if (selectedObject instanceof MPartSashContainer) {
+			stackLayout.topControl = sashProperties;
+			sashProperties.selected(selectedObject);
+		} else if (selectedObject instanceof MPart){
+			stackLayout.topControl = contribItemProperties;
+	        contribItemProperties.selected(selected);
+		} else {
+			stackLayout.topControl = elementProperties;
+			elementProperties.selected(selected);
+		}
+        comp.layout();
+	}
+
+	public void dispose() {
+		contribItemProperties.dispose();
+		stackProperties.dispose();
+		sashProperties.dispose();
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/NewEditor.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/NewEditor.xmi
new file mode 100644
index 0000000..42b1e1f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/NewEditor.xmi
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:Application xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:application="http://www.eclipse.org/ui/2008/UIModel" xsi:schemaLocation="http://www.eclipse.org/ui/2008/UIModel ../../org.eclipse.e4.ui.model.workbench/model/UIElements.ecore"/>
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/UIModelViewer.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/UIModelViewer.xmi
new file mode 100644
index 0000000..84f7ac6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/UIModelViewer.xmi
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:Window xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2008/UIModel" xsi:schemaLocation="http://www.eclipse.org/ui/2008/UIModel ../../org.eclipse.e4.ui.model.workbench/model/UIElements.ecore">
+  <children xsi:type="application:PartSashContainer" horizontal="true">
+    <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.ModelExplorer" name="Model View"/>
+    <children xsi:type="application:PartStack">
+      <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabBasic" name="&amp;Basic"/>
+      <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabAdvanced" name="&amp;Advanced"/>
+      <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView" name="&amp;Javascript"/>
+    </children>
+  </children>
+</application:Window>
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/modelViewer.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/modelViewer.xmi
new file mode 100644
index 0000000..06d1ccf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/modelViewer.xmi
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="ASCII"?>
+<org.eclipse.e4.ui.model.application:MWindow xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:org.eclipse.e4.ui.model.application="http://www.eclipse.org/ui/2008/Application" xsi:schemaLocation="http://www.eclipse.org/ui/2008/Application ../../org.eclipse.e4.ui.model.workbench/model/Application.ecore" xmi:id="_0" id="UI Editor" visible="false" name="UI Model Editor" width="600" height="500">
+  <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+    <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Model View" tooltip="" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.ModelExplorer"/>
+    <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+      <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="&amp;Basic" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabBasic"/>
+      <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="&amp;Advanced" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabAdvanced"/>
+      <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="&amp;Javascript" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView"/>
+    </children>
+    <variables>selection</variables>
+    <weights>50</weights>
+    <weights>50</weights>
+  </children>
+</org.eclipse.e4.ui.model.application:MWindow>
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi
new file mode 100644
index 0000000..1dbfced
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ASCII"?>
+<org.eclipse.e4.ui.model.application:MApplication xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:org.eclipse.e4.ui.model.application="http://www.eclipse.org/ui/2008/Application" xsi:schemaLocation="http://www.eclipse.org/ui/2008/Application ../../org.eclipse.e4.ui.model.workbench/model/Application.ecore">
+  <windows name="Modify Model" x="100" y="100" width="800" height="600">
+    <menu>
+      <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="File">
+        <menu>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" id="" name="Do Nothing"/>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="---" separator="true"/>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+        </menu>
+      </items>
+      <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Edit">
+        <menu>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+        </menu>
+      </items>
+      <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Help">
+        <menu>
+          <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+        </menu>
+      </items>
+    </menu>
+    <children policy="VerticalComposite">
+      <toolBar>
+        <items xsi:type="org.eclipse.e4.ui.model.application:MToolBarItem" iconURI="platform:/plugin/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif" name="You Are Seeing The Default Application.xmi"/>
+      </toolBar>
+      <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="HorizontalSash">
+        <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+          <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+            <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Model View" tooltip="" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ModelView"/>
+          </children>
+        </children>
+        <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+          <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Preview" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView"/>
+          <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+            <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Thumbnails" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.SampleView"/>
+            <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Exif" tooltip="" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.SampleView"/>
+          </children>
+          <weights>70</weights>
+          <weights>30</weights>
+        </children>
+        <weights>30</weights>
+        <weights>70</weights>
+      </children>
+    </children>
+    <handlers URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ExitHandler" command="//@command.0"/>
+  </windows>
+  <command id="org.eclipse.e4.demo.modifier.exit" name="Exit"/>
+</org.eclipse.e4.ui.model.application:MApplication>
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.classpath b/examples/org.eclipse.e4.demo.simpleide.dialogs/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.project b/examples/org.eclipse.e4.demo.simpleide.dialogs/.project
new file mode 100644
index 0000000..7e61f11
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.dialogs</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a9a6fc3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat May 22 18:21:58 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..8c0e9bf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:08:04 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.dialogs/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..672feb5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Dialogs
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.dialogs
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.e4.demo.simpleide.sharedimages;bundle-version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/build.properties b/examples/org.eclipse.e4.demo.simpleide.dialogs/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/ContainerSelectionDialog.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/ContainerSelectionDialog.java
new file mode 100644
index 0000000..0a9f01b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/ContainerSelectionDialog.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   IBM Corporation - initial API and implementation 
+ *   Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog
+ *     font should be activated and used by other components.
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.components.ContainerSelectionGroup;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.components.ISelectionValidator;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A standard selection dialog which solicits a container resource from the user.
+ * The <code>getResult</code> method returns the selected container resource.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example:
+ * <pre>
+ * ContainerSelectionDialog dialog =
+ *    new ContainerSelectionDialog(getShell(), initialSelection, allowNewContainerName(), msg);
+ *	dialog.open();
+ *	Object[] result = dialog.getResult();
+ * </pre> 	
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ContainerSelectionDialog extends SelectionDialog<IPath> {
+    /**
+	 * 
+	 */
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+	// the widget group;
+    ContainerSelectionGroup group;
+
+    // the root resource to populate the viewer with
+    private IContainer initialSelection;
+
+    // allow the user to type in a new container name
+    private boolean allowNewContainerName = true;
+
+    // the validation message
+    Label statusMessage;
+
+    //for validating the selection
+    ISelectionValidator validator;
+
+    // show closed projects by default
+    private boolean showClosedProjects = true;
+    
+    private IImageService imageService;
+
+    /**
+     * Creates a resource container selection dialog rooted at the given resource.
+     * All selections are considered valid. 
+     *
+     * @param parentShell the parent shell
+     * @param initialRoot the initial selection in the tree
+     * @param allowNewContainerName <code>true</code> to enable the user to type in
+     *  a new container name, and <code>false</code> to restrict the user to just
+     *  selecting from existing ones
+     * @param message the message to be displayed at the top of this dialog, or
+     *    <code>null</code> to display a default message
+     */
+    public ContainerSelectionDialog(Shell parentShell, IContainer initialRoot,
+            boolean allowNewContainerName, String message, IImageService imageService) {
+        super(parentShell);
+        this.imageService = imageService;
+        setTitle(Messages.ContainerSelectionDialog_title);
+        this.initialSelection = initialRoot;
+        this.allowNewContainerName = allowNewContainerName;
+        if (message != null) {
+			setMessage(message);
+		} else {
+			setMessage(Messages.ContainerSelectionDialog_message);
+		}
+        setShellStyle(getShellStyle() | SWT.SHEET);
+    }
+
+    /* (non-Javadoc)
+     * Method declared in Window.
+     */
+    protected void configureShell(Shell shell) {
+        super.configureShell(shell);
+        
+//FIXME We need a help system        
+//        PlatformUI.getWorkbench().getHelpSystem()
+//                .setHelp(shell, IIDEHelpContextIds.CONTAINER_SELECTION_DIALOG);
+    }
+
+    /* (non-Javadoc)
+     * Method declared on Dialog.
+     */
+    protected Control createDialogArea(Composite parent) {
+        // create composite 
+        Composite area = (Composite) super.createDialogArea(parent);
+
+        Listener listener = new Listener() {
+            public void handleEvent(Event event) {
+                if (statusMessage != null && validator != null) {
+                    String errorMsg = validator.isValid(group
+                            .getContainerFullPath());
+                    if (errorMsg == null || errorMsg.equals(EMPTY_STRING)) {
+                        statusMessage.setText(EMPTY_STRING);
+                        getOkButton().setEnabled(true);
+                    } else {
+                        statusMessage.setText(errorMsg);
+                        getOkButton().setEnabled(false);
+                    }
+                }
+            }
+        };
+
+        // container selection group
+        group = new ContainerSelectionGroup(area, listener,
+                allowNewContainerName, getMessage(), showClosedProjects,imageService);
+        if (initialSelection != null) {
+            group.setSelectedContainer(initialSelection);
+        }
+
+        statusMessage = new Label(area, SWT.WRAP);
+        statusMessage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        statusMessage.setText(" \n "); //$NON-NLS-1$
+        statusMessage.setFont(parent.getFont());
+
+        return dialogArea;
+    }
+
+    /**
+     * The <code>ContainerSelectionDialog</code> implementation of this 
+     * <code>Dialog</code> method builds a list of the selected resource containers
+     * for later retrieval by the client and closes this dialog.
+     */
+    protected void okPressed() {
+
+        List<IPath> chosenContainerPathList = new ArrayList<IPath>();
+        IPath returnValue = group.getContainerFullPath();
+        if (returnValue != null) {
+			chosenContainerPathList.add(returnValue);
+		}
+        setResult(chosenContainerPathList);
+        super.okPressed();
+    }
+
+    /**
+     * Sets the validator to use.  
+     * 
+     * @param validator A selection validator
+     */
+    public void setValidator(ISelectionValidator validator) {
+        this.validator = validator;
+    }
+
+    /**
+     * Set whether or not closed projects should be shown
+     * in the selection dialog.
+     * 
+     * @param show Whether or not to show closed projects.
+     */
+    public void showClosedProjects(boolean show) {
+        this.showClosedProjects = show;
+    }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/SelectionDialog.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/SelectionDialog.java
new file mode 100644
index 0000000..495be03
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/SelectionDialog.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * The abstract implementation of a selection dialog. It can be primed with
+ * initial selections (<code>setInitialSelections</code>), and returns the
+ * final selection (via <code>getResult</code>) after completion.
+ * <p>
+ * Clients may subclass this dialog to inherit its selection facilities.
+ * </p>
+ */
+public abstract class SelectionDialog<T> extends TrayDialog {
+	// the final collection of selected elements, or null if this dialog was
+	// canceled
+	private List<T> result;
+
+	// a collection of the initially-selected elements
+	private List<T> initialSelections = new ArrayList<T>();
+
+	// title of dialog
+	private String title;
+
+	// message to show user
+	private String message = ""; //$NON-NLS-1$
+
+	// dialog bounds strategy (since 3.2)
+	private int dialogBoundsStrategy = Dialog.DIALOG_PERSISTLOCATION | Dialog.DIALOG_PERSISTSIZE;
+
+	// dialog settings for storing bounds (since 3.2)
+	private IDialogSettings dialogBoundsSettings = null;
+
+	static String SELECT_ALL_TITLE = Messages.SelectionDialog_selectLabel;
+
+	static String DESELECT_ALL_TITLE = Messages.SelectionDialog_deselectLabel;
+
+	/**
+	 * Creates a dialog instance. Note that the dialog will have no visual
+	 * representation (no widgets) until it is told to open.
+	 * 
+	 * @param parentShell
+	 *            the parent shell
+	 */
+	protected SelectionDialog(Shell parentShell) {
+		super(parentShell);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared in Window.
+	 */
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		if (title != null) {
+			shell.setText(title);
+		}
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on Dialog.
+	 */
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
+				true);
+		createButton(parent, IDialogConstants.CANCEL_ID,
+				IDialogConstants.CANCEL_LABEL, false);
+	}
+
+	/**
+	 * Creates the message area for this dialog.
+	 * <p>
+	 * This method is provided to allow subclasses to decide where the message
+	 * will appear on the screen.
+	 * </p>
+	 * 
+	 * @param composite
+	 *            the parent composite
+	 * @return the message label
+	 */
+	protected Label createMessageArea(Composite composite) {
+		Label label = new Label(composite, SWT.NONE);
+		if (message != null) {
+			label.setText(message);
+		}
+		label.setFont(composite.getFont());
+		return label;
+	}
+
+//	/**
+//	 * Returns the initial selection in this selection dialog.
+//	 * 
+//	 * @deprecated use getInitialElementSelections() instead
+//	 * @return the list of initial selected elements or null
+//	 */
+//	protected List getInitialSelections() {
+//		if (initialSelections.isEmpty()) {
+//			return null;
+//		}
+//		return getInitialElementSelections();
+//	}
+
+	/**
+	 * Returns the list of initial element selections.
+	 * 
+	 * @return List
+	 */
+	protected List<T> getInitialElementSelections() {
+		return initialSelections;
+	}
+
+	/**
+	 * Returns the message for this dialog.
+	 * 
+	 * @return the message for this dialog
+	 */
+	protected String getMessage() {
+		return message;
+	}
+
+	/**
+	 * Returns the ok button.
+	 * 
+	 * @return the ok button or <code>null</code> if the button is not created
+	 *         yet.
+	 */
+	public Button getOkButton() {
+		return getButton(IDialogConstants.OK_ID);
+	}
+
+	/**
+	 * Returns the list of selections made by the user, or <code>null</code>
+	 * if the selection was canceled.
+	 * 
+	 * @return the array of selected elements, or <code>null</code> if Cancel
+	 *         was pressed
+	 */
+	public List<T> getResult() {
+		return result;
+	}
+
+	/**
+	 * Sets the initial selection in this selection dialog to the given
+	 * elements.
+	 * 
+	 * @param selectedElements
+	 *            the array of elements to select
+	 */
+	public void setInitialSelections(T[] selectedElements) {
+		initialSelections = Arrays.asList(selectedElements);
+	}
+
+	/**
+	 * Sets the initial selection in this selection dialog to the given
+	 * elements.
+	 * 
+	 * @param selectedElements
+	 *            the List of elements to select
+	 */
+	public void setInitialElementSelections(List<T> selectedElements) {
+		initialSelections = selectedElements;
+	}
+
+	/**
+	 * Sets the message for this dialog.
+	 * 
+	 * @param message
+	 *            the message
+	 */
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	/**
+	 * Set the selections made by the user, or <code>null</code> if the
+	 * selection was canceled.
+	 * 
+	 * @param newResult
+	 *            list of selected elements, or <code>null</code> if Cancel
+	 *            was pressed
+	 */
+	protected void setResult(List<T> newResult) {
+		if (newResult == null) {
+			result = null;
+		} else {
+			result = new ArrayList<T>();
+		}
+	}
+
+	/**
+	 * Set the selections made by the user, or <code>null</code> if the
+	 * selection was canceled.
+	 * <p>
+	 * The selections may accessed using <code>getResult</code>.
+	 * </p>
+	 * 
+	 * @param newResult -
+	 *            the new values
+	 * @since 2.0
+	 */
+	protected void setSelectionResult(List<T> newResult) {
+		result = newResult;
+	}
+
+	/**
+	 * Sets the title for this dialog.
+	 * 
+	 * @param title
+	 *            the title
+	 */
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	/**
+	 * Set the dialog settings that should be used to save the bounds of this
+	 * dialog. This method is provided so that clients that directly use
+	 * SelectionDialogs without subclassing them may specify how the bounds of
+	 * the dialog are to be saved.
+	 * 
+	 * @param settings
+	 *            the {@link IDialogSettings} that should be used to store the
+	 *            bounds of the dialog
+	 * 
+	 * @param strategy
+	 *            the integer constant specifying how the bounds are saved.
+	 *            Specified using {@link Dialog#DIALOG_PERSISTLOCATION}
+	 *            and {@link Dialog#DIALOG_PERSISTSIZE}.
+	 * 
+	 * @since 3.2
+	 * 
+	 * @see Dialog#getDialogBoundsStrategy()
+	 * @see Dialog#getDialogBoundsSettings()
+	 */
+	public void setDialogBoundsSettings(IDialogSettings settings, int strategy) {
+		dialogBoundsStrategy = strategy;
+		dialogBoundsSettings = settings;
+	}
+
+	/**
+	 * Gets the dialog settings that should be used for remembering the bounds
+	 * of the dialog, according to the dialog bounds strategy. Overridden to
+	 * provide the dialog settings that were set using
+	 * {@link #setDialogBoundsSettings(IDialogSettings, int)}.
+	 * 
+	 * @return the dialog settings used to store the dialog's location and/or
+	 *         size, or <code>null</code> if the dialog's bounds should not be
+	 *         stored.
+	 * 
+	 * @since 3.2
+	 * 
+	 * @see Dialog#getDialogBoundsStrategy()
+	 * @see #setDialogBoundsSettings(IDialogSettings, int)
+	 */
+	protected IDialogSettings getDialogBoundsSettings() {
+		return dialogBoundsSettings;
+	}
+
+	/**
+	 * Get the integer constant that describes the strategy for persisting the
+	 * dialog bounds. Overridden to provide the dialog bounds strategy that was
+	 * set using {@link #setDialogBoundsSettings(IDialogSettings, int)}.
+	 * 
+	 * @return the constant describing the strategy for persisting the dialog
+	 *         bounds.
+	 * 
+	 * @since 3.2
+	 * @see Dialog#DIALOG_PERSISTLOCATION
+	 * @see Dialog#DIALOG_PERSISTSIZE
+	 * @see Dialog#getDialogBoundsSettings()
+	 * @see #setDialogBoundsSettings(IDialogSettings, int)
+	 */
+	protected int getDialogBoundsStrategy() {
+		return dialogBoundsStrategy;
+	}
+	
+    /**
+	 * @since 3.4
+	 */
+    protected boolean isResizable() {
+    	return true;
+    }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.java
new file mode 100644
index 0000000..fa6b0e0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.java
@@ -0,0 +1,25 @@
+package org.eclipse.e4.demo.simpleide.dialogs.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages {
+	
+	public static String SelectionDialog_selectLabel;
+	public static String SelectionDialog_deselectLabel;
+	
+	public static String GoHome_text;
+	public static String GoHome_toolTip;
+	public static String GoBack_toolTip;
+	public static String GoInto_text;
+	public static String GoInto_toolTip;
+	public static String GoBack_text;
+	
+	public static String ContainerGroup_message;
+	public static String ContainerGroup_selectFolder;
+	public static String ContainerSelectionDialog_title;
+	public static String ContainerSelectionDialog_message;
+
+	static {
+		NLS.initializeMessages(Messages.class.getName(), Messages.class);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.properties b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.properties
new file mode 100644
index 0000000..3fdaacf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.properties
@@ -0,0 +1,9 @@
+SelectionDialog_selectLabel = &Select All
+SelectionDialog_deselectLabel = &Deselect All
+
+GoHome_text = Go &Home
+GoHome_toolTip = Home
+GoBack_text = Go &Back
+GoBack_toolTip = Back
+GoInto_text = Go &Into
+GoInto_toolTip = Go Into
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerContentProvider.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerContentProvider.java
new file mode 100644
index 0000000..b07016e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerContentProvider.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Provides content for a tree viewer that shows only containers.
+ */
+public class ContainerContentProvider implements ITreeContentProvider {
+    private boolean showClosedProjects = true;
+
+    /**
+     * Creates a new ContainerContentProvider.
+     */
+    public ContainerContentProvider() {
+    }
+
+    /**
+     * The visual part that is using this content provider is about
+     * to be disposed. Deallocate all allocated SWT resources.
+     */
+    public void dispose() {
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+     */
+    public Object[] getChildren(Object element) {
+        if (element instanceof IWorkspace) {
+            // check if closed projects should be shown
+            IProject[] allProjects = ((IWorkspace) element).getRoot()
+                    .getProjects();
+            if (showClosedProjects) {
+				return allProjects;
+			}
+
+            ArrayList<IProject> accessibleProjects = new ArrayList<IProject>();
+            for (int i = 0; i < allProjects.length; i++) {
+                if (allProjects[i].isOpen()) {
+                    accessibleProjects.add(allProjects[i]);
+                }
+            }
+            return accessibleProjects.toArray();
+        } else if (element instanceof IContainer) {
+            IContainer container = (IContainer) element;
+            if (container.isAccessible()) {
+                try {
+                    List<IResource> children = new ArrayList<IResource>();
+                    IResource[] members = container.members();
+                    for (int i = 0; i < members.length; i++) {
+                        if (members[i].getType() != IResource.FILE) {
+                            children.add(members[i]);
+                        }
+                    }
+                    return children.toArray();
+                } catch (CoreException e) {
+                    // this should never happen because we call #isAccessible before invoking #members
+                }
+            }
+        }
+        return new Object[0];
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+     */
+    public Object[] getElements(Object element) {
+        return getChildren(element);
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+     */
+    public Object getParent(Object element) {
+        if (element instanceof IResource) {
+			return ((IResource) element).getParent();
+		}
+        return null;
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+     */
+    public boolean hasChildren(Object element) {
+        return getChildren(element).length > 0;
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged
+     */
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+    }
+
+    /**
+     * Specify whether or not to show closed projects in the tree 
+     * viewer.  Default is to show closed projects.
+     * 
+     * @param show boolean if false, do not show closed projects in the tree
+     */
+    public void showClosedProjects(boolean show) {
+        showClosedProjects = show;
+    }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerSelectionGroup.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerSelectionGroup.java
new file mode 100644
index 0000000..1822e1a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerSelectionGroup.java
@@ -0,0 +1,355 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Igor Fedorenko <igorfie@yahoo.com> - 
+ *     		Fix for Bug 136921 [IDE] New File dialog locks for 20 seconds
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.osgi.util.TextProcessor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Workbench-level composite for choosing a container.
+ */
+public class ContainerSelectionGroup extends Composite {
+	// The listener to notify of events
+	private Listener listener;
+
+	// Enable user to type in new container name
+	private boolean allowNewContainerName = true;
+
+	// show all projects by default
+	private boolean showClosedProjects = true;
+
+	// Last selection made by user
+	private IContainer selectedContainer;
+
+	// handle on parts
+	private Text containerNameField;
+
+	TreeViewer treeViewer;
+	
+	private IImageService imageService;
+
+	// the message to display at the top of this dialog
+	private static final String DEFAULT_MSG_NEW_ALLOWED = Messages.ContainerGroup_message;
+
+	private static final String DEFAULT_MSG_SELECT_ONLY = Messages.ContainerGroup_selectFolder;
+
+	// sizing constants
+	private static final int SIZING_SELECTION_PANE_WIDTH = 320;
+
+	private static final int SIZING_SELECTION_PANE_HEIGHT = 300;
+
+	/**
+	 * Creates a new instance of the widget.
+	 * 
+	 * @param parent
+	 *            The parent widget of the group.
+	 * @param listener
+	 *            A listener to forward events to. Can be null if no listener is
+	 *            required.
+	 * @param allowNewContainerName
+	 *            Enable the user to type in a new container name instead of
+	 *            just selecting from the existing ones.
+	 */
+	public ContainerSelectionGroup(Composite parent, Listener listener,
+			boolean allowNewContainerName, IImageService imageService) {
+		this(parent, listener, allowNewContainerName, null, imageService);
+	}
+
+	/**
+	 * Creates a new instance of the widget.
+	 * 
+	 * @param parent
+	 *            The parent widget of the group.
+	 * @param listener
+	 *            A listener to forward events to. Can be null if no listener is
+	 *            required.
+	 * @param allowNewContainerName
+	 *            Enable the user to type in a new container name instead of
+	 *            just selecting from the existing ones.
+	 * @param message
+	 *            The text to present to the user.
+	 */
+	public ContainerSelectionGroup(Composite parent, Listener listener,
+			boolean allowNewContainerName, String message, IImageService imageService) {
+		this(parent, listener, allowNewContainerName, message, true, imageService);
+	}
+
+	/**
+	 * Creates a new instance of the widget.
+	 * 
+	 * @param parent
+	 *            The parent widget of the group.
+	 * @param listener
+	 *            A listener to forward events to. Can be null if no listener is
+	 *            required.
+	 * @param allowNewContainerName
+	 *            Enable the user to type in a new container name instead of
+	 *            just selecting from the existing ones.
+	 * @param message
+	 *            The text to present to the user.
+	 * @param showClosedProjects
+	 *            Whether or not to show closed projects.
+	 */
+	public ContainerSelectionGroup(Composite parent, Listener listener,
+			boolean allowNewContainerName, String message,
+			boolean showClosedProjects, IImageService imageService) {
+		this(parent, listener, allowNewContainerName, message,
+				showClosedProjects, SIZING_SELECTION_PANE_HEIGHT,
+				SIZING_SELECTION_PANE_WIDTH,imageService);
+	}
+
+	/**
+	 * Creates a new instance of the widget.
+	 * 
+	 * @param parent
+	 *            The parent widget of the group.
+	 * @param listener
+	 *            A listener to forward events to. Can be null if no listener is
+	 *            required.
+	 * @param allowNewContainerName
+	 *            Enable the user to type in a new container name instead of
+	 *            just selecting from the existing ones.
+	 * @param message
+	 *            The text to present to the user.
+	 * @param showClosedProjects
+	 *            Whether or not to show closed projects.
+	 * @param heightHint
+	 *            height hint for the drill down composite
+	 * @param widthHint
+	 *            width hint for the drill down composite
+	 */
+	public ContainerSelectionGroup(Composite parent, Listener listener,
+			boolean allowNewContainerName, String message,
+			boolean showClosedProjects, int heightHint, int widthHint, IImageService imageService) {
+		super(parent, SWT.NONE);
+		this.imageService = imageService;
+		this.listener = listener;
+		this.allowNewContainerName = allowNewContainerName;
+		this.showClosedProjects = showClosedProjects;
+		if (message != null) {
+			createContents(message, heightHint, widthHint);
+		} else if (allowNewContainerName) {
+			createContents(DEFAULT_MSG_NEW_ALLOWED, heightHint, widthHint);
+		} else {
+			createContents(DEFAULT_MSG_SELECT_ONLY, heightHint, widthHint);
+		}
+	}
+
+	/**
+	 * The container selection has changed in the tree view. Update the
+	 * container name field value and notify all listeners.
+	 * 
+	 * @param container
+	 *            The container that changed
+	 */
+	public void containerSelectionChanged(IContainer container) {
+		selectedContainer = container;
+
+		if (allowNewContainerName) {
+			if (container == null) {
+				containerNameField.setText("");//$NON-NLS-1$
+			} else {
+				String text = TextProcessor.process(container.getFullPath()
+						.makeRelative().toString());
+				containerNameField.setText(text);
+				containerNameField.setToolTipText(text);
+			}
+		}
+
+		// fire an event so the parent can update its controls
+		if (listener != null) {
+			Event changeEvent = new Event();
+			changeEvent.type = SWT.Selection;
+			changeEvent.widget = this;
+			listener.handleEvent(changeEvent);
+		}
+	}
+
+	/**
+	 * Creates the contents of the composite.
+	 * 
+	 * @param message
+	 */
+	public void createContents(String message) {
+		createContents(message, SIZING_SELECTION_PANE_HEIGHT,
+				SIZING_SELECTION_PANE_WIDTH);
+	}
+
+	/**
+	 * Creates the contents of the composite.
+	 * 
+	 * @param message
+	 * @param heightHint
+	 * @param widthHint
+	 */
+	public void createContents(String message, int heightHint, int widthHint) {
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = 0;
+		setLayout(layout);
+		setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+		Label label = new Label(this, SWT.WRAP);
+		label.setText(message);
+		label.setFont(this.getFont());
+
+		if (allowNewContainerName) {
+			containerNameField = new Text(this, SWT.SINGLE | SWT.BORDER);
+			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+			gd.widthHint = widthHint;
+			containerNameField.setLayoutData(gd);
+			containerNameField.addListener(SWT.Modify, listener);
+			containerNameField.setFont(this.getFont());
+		} else {
+			// filler...
+			new Label(this, SWT.NONE);
+		}
+
+		createTreeViewer(heightHint);
+		Dialog.applyDialogFont(this);
+	}
+
+	/**
+	 * Returns a new drill down viewer for this dialog.
+	 * 
+	 * @param heightHint
+	 *            height hint for the drill down composite
+	 */
+	protected void createTreeViewer(int heightHint) {
+		// Create drill down.
+		DrillDownComposite drillDown = new DrillDownComposite(this, SWT.BORDER,imageService);
+		GridData spec = new GridData(SWT.FILL, SWT.FILL, true, true);
+		spec.widthHint = SIZING_SELECTION_PANE_WIDTH;
+		spec.heightHint = heightHint;
+		drillDown.setLayoutData(spec);
+
+		// Create tree viewer inside drill down.
+		treeViewer = new TreeViewer(drillDown, SWT.NONE);
+		drillDown.setChildTree(treeViewer);
+		ContainerContentProvider cp = new ContainerContentProvider();
+		cp.showClosedProjects(showClosedProjects);
+		treeViewer.setContentProvider(cp);
+		
+//FIXME We need a WorkbenchLabelProvider replacement
+//		treeViewer.setLabelProvider(WorkbenchLabelProvider
+//				.getDecoratingWorkbenchLabelProvider());
+		treeViewer.setComparator(new ViewerComparator());
+		treeViewer.setUseHashlookup(true);
+		treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				IStructuredSelection selection = (IStructuredSelection) event
+						.getSelection();
+				containerSelectionChanged((IContainer) selection
+						.getFirstElement()); // allow null
+			}
+		});
+		treeViewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				ISelection selection = event.getSelection();
+				if (selection instanceof IStructuredSelection) {
+					Object item = ((IStructuredSelection) selection)
+							.getFirstElement();
+					if (item == null) {
+						return;
+					}
+					if (treeViewer.getExpandedState(item)) {
+						treeViewer.collapseToLevel(item, 1);
+					} else {
+						treeViewer.expandToLevel(item, 1);
+					}
+				}
+			}
+		});
+
+		// This has to be done after the viewer has been laid out
+		treeViewer.setInput(ResourcesPlugin.getWorkspace());
+	}
+
+	/**
+	 * Returns the currently entered container name. Null if the field is empty.
+	 * Note that the container may not exist yet if the user entered a new
+	 * container name in the field.
+	 * 
+	 * @return IPath
+	 */
+	public IPath getContainerFullPath() {
+		if (allowNewContainerName) {
+			String pathName = containerNameField.getText();
+			if (pathName == null || pathName.length() < 1) {
+				return null;
+			}
+			// The user may not have made this absolute so do it for them
+			return (new Path(TextProcessor.deprocess(pathName))).makeAbsolute();
+
+		}
+		if (selectedContainer == null)
+			return null;
+		return selectedContainer.getFullPath();
+
+	}
+
+	/**
+	 * Gives focus to one of the widgets in the group, as determined by the
+	 * group.
+	 */
+	public void setInitialFocus() {
+		if (allowNewContainerName) {
+			containerNameField.setFocus();
+		} else {
+			treeViewer.getTree().setFocus();
+		}
+	}
+
+	/**
+	 * Sets the selected existing container.
+	 * 
+	 * @param container
+	 */
+	public void setSelectedContainer(IContainer container) {
+		selectedContainer = container;
+
+		// expand to and select the specified container
+		List<IContainer> itemsToExpand = new ArrayList<IContainer>();
+		IContainer parent = container.getParent();
+		while (parent != null) {
+			itemsToExpand.add(0, parent);
+			parent = parent.getParent();
+		}
+		treeViewer.setExpandedElements(itemsToExpand.toArray());
+		treeViewer.setSelection(new StructuredSelection(container), true);
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownAdapter.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownAdapter.java
new file mode 100644
index 0000000..6a241aa
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownAdapter.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.Arrays;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.e4.demo.simpleide.services.IImageService.IImagePool;
+import org.eclipse.e4.demo.simpleide.sharedimages.SharedImageKeys;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+
+/**
+ * Implements a simple web style navigation metaphor for a <code>TreeViewer</code>.  
+ * Home, back, and "drill into" functions are supported for the viewer,
+ * <p>
+ * To use the <code>DrillDownAdapter</code> ..
+ * </p>
+ * <ul>
+ * <li>Create an instance of <code>TreeViewer</code>. </li>
+ * <li>Create a <code>DrillDownAdapter</code> for the viewer. </li>
+ * <li>Create a container for your viewer with a toolbar or a popup menu.
+ *		Add actions for "goBack", "goHome", and "goInto" to either one by calling
+ *		</code>addNavigationActions</code> with the popup menu or toolbar.</li>
+ * </ol>
+ * <p>
+ * If the input for the underlying viewer is changed by something other than the 
+ * adapter the <code>reset</code> method should be called.  This will clear
+ * the drill stack and update the navigation buttons to reflect the new 
+ * state of the underlying viewer.
+ * </p>
+ * </p>
+ */
+public class DrillDownAdapter implements ISelectionChangedListener {
+    private TreeViewer fChildTree;
+
+    private DrillStack fDrillStack;
+
+    private Action homeAction;
+
+    private Action backAction;
+
+    private Action forwardAction;
+    
+    private IImagePool pool;
+
+    /**
+     * Allocates a new DrillDownTreePart.
+     *
+     * @param tree the target tree for refocusing
+     */
+    public DrillDownAdapter(TreeViewer tree, IImageService imageService) {
+    	pool = imageService.getControlPool(tree.getControl());
+        fDrillStack = new DrillStack();
+        fChildTree = tree;
+    }
+
+    /**
+     * Adds actions for "go back", "go home", and "go into" to a menu manager.
+     *
+     * @param manager is the target manager to update
+     */
+    public void addNavigationActions(IMenuManager manager) {
+        createActions();
+        manager.add(homeAction);
+        manager.add(backAction);
+        manager.add(forwardAction);
+        updateNavigationButtons();
+    }
+
+    /**
+     * Adds actions for "go back", "go home", and "go into" to a tool bar manager.
+     *
+     * @param toolBar is the target manager to update
+     */
+    public void addNavigationActions(IToolBarManager toolBar) {
+        createActions();
+        toolBar.add(homeAction);
+        toolBar.add(backAction);
+        toolBar.add(forwardAction);
+        updateNavigationButtons();
+    }
+
+    /**
+     * Returns whether expansion is possible for the current selection.  This
+     * will only be true if it has children.
+     *
+     * @param element the object to test for expansion
+     * @return <code>true</code> if expansion is possible; otherwise 
+     *		return <code>false</code
+     */
+    public boolean canExpand(Object element) {
+        return fChildTree.isExpandable(element);
+    }
+
+    /**
+     * Returns whether "go back" is possible for child tree.  This is only possible 
+     * if the client has performed one or more drilling operations.
+     *
+     * @return <code>true</code> if "go back" is possible; <code>false</code> otherwise
+     */
+    public boolean canGoBack() {
+        return fDrillStack.canGoBack();
+    }
+
+    /**
+     * Returns whether "go home" is possible for child tree.  This is only possible 
+     * if the client has performed one or more drilling operations.
+     *
+     * @return <code>true</code> if "go home" is possible; <code>false</code> otherwise
+     */
+    public boolean canGoHome() {
+        return fDrillStack.canGoHome();
+    }
+
+    /**
+     * Returns whether "go into" is possible for child tree.  This is only possible 
+     * if the current selection in the client has one item and it has children.
+     *
+     * @return <code>true</code> if "go into" is possible; <code>false</code> otherwise
+     */
+    public boolean canGoInto() {
+        IStructuredSelection oSelection = (IStructuredSelection) fChildTree
+                .getSelection();
+        if (oSelection == null || oSelection.size() != 1) {
+			return false;
+		}
+        Object anElement = oSelection.getFirstElement();
+        return canExpand(anElement);
+    }
+
+    /**
+     * Create the actions for navigation.
+     *
+     */
+    private void createActions() {
+        // Only do this once.
+        if (homeAction != null) {
+			return;
+		}
+
+        // Home.	
+        homeAction = new Action(Messages.GoHome_text) {
+            public void run() {
+                goHome();
+            }
+        };
+        homeAction
+                .setToolTipText(Messages.GoHome_toolTip);
+        homeAction
+                .setImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_HOME_NAV)));
+
+        // Back.
+        backAction = new Action(Messages.GoBack_text) {
+            public void run() {
+                goBack();
+            }
+        };
+        backAction
+                .setToolTipText(Messages.GoBack_toolTip); 
+        backAction.setImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_BACK)));
+        backAction.setDisabledImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_BACK_DISABLED)));
+
+        // Forward.
+        forwardAction = new Action(Messages.GoInto_text) { 
+            public void run() {
+                goInto();
+            }
+        };
+        forwardAction.setToolTipText(Messages.GoInto_toolTip); 
+        forwardAction.setImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_FORWARD)));
+        forwardAction.setDisabledImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_FORWARD_DISABLED)));
+
+        // Update the buttons when a selection change occurs.
+        fChildTree.addSelectionChangedListener(this);
+        updateNavigationButtons();
+    }
+
+    /**
+     * Expands the given items in the tree.  The list of items passed should be
+     * derived by calling <code>getExpanded</code>.
+     *
+     * @param items is a list of items within the tree which should be expanded
+     */
+    private void expand(List items) {
+        fChildTree.setExpandedElements(items.toArray());
+    }
+
+    /**
+     * Returns a list of elements corresponding to expanded nodes in 
+     * child tree.
+     *
+     * @return a list of expandd elements
+     */
+    private List getExpanded() {
+        return Arrays.asList(fChildTree.getExpandedElements());
+    }
+
+    /**
+     * Reverts the input for the tree back to the state when <code>goInto</code>
+     * was last called.
+     * <p>
+     * A frame is removed from the drill stack.  Then that frame is used to reset the
+     * input and expansion state for the child tree.
+     * </p>
+     */
+    public void goBack() {
+        Object currentInput = fChildTree.getInput();
+        DrillFrame oFrame = fDrillStack.goBack();
+        Object input = oFrame.getElement();
+        fChildTree.setInput(input);
+        expand(oFrame.getExpansion());
+        // if there was a selection, it should have been preserved,
+        // but if not, select the element that was drilled into
+        if (fChildTree.getSelection().isEmpty()) {
+			fChildTree
+                    .setSelection(new StructuredSelection(currentInput), true);
+		}
+        updateNavigationButtons();
+    }
+
+    /**
+     * Reverts the input for the tree back to the state when the adapter was
+     * created.
+     * <p>
+     * All of the frames are removed from the drill stack.  Then the oldest frame is 
+     * used to reset the input and expansion state for the child tree.
+     * </p>
+     */
+    public void goHome() {
+        Object currentInput = fChildTree.getInput();
+        DrillFrame oFrame = fDrillStack.goHome();
+        Object input = oFrame.getElement();
+        fChildTree.setInput(input);
+        expand(oFrame.getExpansion());
+        // if there was a selection, it should have been preserved,
+        // but if not, select the element that was last drilled into
+        if (fChildTree.getSelection().isEmpty()) {
+			fChildTree
+                    .setSelection(new StructuredSelection(currentInput), true);
+		}
+        updateNavigationButtons();
+    }
+
+    /**
+     * Sets the input for the tree to the current selection.
+     * <p>
+     * The current input and expansion state are saved in a frame and added to the 
+     * drill stack.  Then the input for the tree is changed to be the current selection.  
+     * The expansion state for the tree is maintained during the operation.
+     * </p><p>
+     * On return the client may revert back to the previous state by invoking 
+     * <code>goBack</code> or <code>goHome</code>.
+     * </p>
+     */
+    public void goInto() {
+        IStructuredSelection sel = (IStructuredSelection) fChildTree
+                .getSelection();
+        Object element = sel.getFirstElement();
+        goInto(element);
+    }
+
+    /**
+     * Sets the input for the tree to a particular item in the tree.
+     * <p>
+     * The current input and expansion state are saved in a frame and added to the 
+     * drill stack.  Then the input for the tree is changed to be <code>newInput</code>.  
+     * The expansion state for the tree is maintained during the operation.
+     * </p><p>
+     * On return the client may revert back to the previous state by invoking 
+     * <code>goBack</code> or <code>goHome</code>.
+     * </p>
+     *
+     * @param newInput the new input element
+     */
+    public void goInto(Object newInput) {
+        // If we can drill ..
+        if (canExpand(newInput)) {
+            // Save the old state.
+            Object oldInput = fChildTree.getInput();
+            List expandedList = getExpanded();
+            fDrillStack.add(new DrillFrame(oldInput, "null", expandedList));//$NON-NLS-1$
+
+            // Install the new state.
+            fChildTree.setInput(newInput);
+            expand(expandedList);
+            updateNavigationButtons();
+        }
+    }
+
+    /**
+     * Resets the drill down adapter. 
+     * <p>
+     * This method is typically called when the input for the underlying view
+     * is reset by something other than the adapter.
+     * On return the drill stack has been cleared and the navigation buttons
+     * reflect the new state of the underlying viewer.
+     * </p>
+     */
+    public void reset() {
+        fDrillStack.reset();
+        updateNavigationButtons();
+    }
+
+    /**
+     * Updates the navigation buttons when a selection change occurs
+     * in the tree.
+     */
+    public void selectionChanged(SelectionChangedEvent event) {
+        updateNavigationButtons();
+    }
+
+    /**
+     * Updates the enabled state for each navigation button.  
+     */
+    protected void updateNavigationButtons() {
+        if (homeAction != null) {
+            homeAction.setEnabled(canGoHome());
+            backAction.setEnabled(canGoBack());
+            forwardAction.setEnabled(canGoInto());
+        }
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownComposite.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownComposite.java
new file mode 100644
index 0000000..49dfa4b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownComposite.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+
+/**
+ * Class <code>DrillDownComposite</code> implements a simple web
+ * style navigation metaphor.  Home, back, and "drill into" buttons are
+ * added to a tree viewer for easier navigation.
+ * <p>
+ * To use the DrillDownComposite..
+ * </p>
+ * <ul>
+ * <li>Create an instance of <code>DrillDownComposite</code>.</li>
+ * <li>Create a tree viewer.  </li>
+ * <li>Pass the second tree viewer into the composite by 
+ *   calling <code>setChildTree</code>.</li>
+ * </ol>
+ */
+public class DrillDownComposite extends Composite {
+    private ToolBarManager toolBarMgr;
+
+    private TreeViewer fChildTree;
+
+    private DrillDownAdapter adapter;
+    
+    private IImageService imageService;
+
+    /**
+     * Constructs a new DrillDownTreeViewer.
+     *
+     * @param parent the parent composite for this control
+     * @param style the SWT style for this control
+     */
+    public DrillDownComposite(Composite parent, int style, IImageService imageService) {
+        super(parent, style);
+        this.imageService = imageService;
+        createNavigationButtons();
+    }
+
+    /**
+     * Creates the navigation buttons for this viewer.
+     */
+    protected void createNavigationButtons() {
+        GridData gid;
+        GridLayout layout;
+
+        // Define layout.
+        layout = new GridLayout();
+        layout.marginHeight = layout.marginWidth = layout.horizontalSpacing = layout.verticalSpacing = 0;
+        setLayout(layout);
+
+        // Create a toolbar.
+        toolBarMgr = new ToolBarManager(SWT.FLAT);
+        ToolBar toolBar = toolBarMgr.createControl(this);
+        gid = new GridData();
+        gid.horizontalAlignment = GridData.FILL;
+        gid.verticalAlignment = GridData.BEGINNING;
+        toolBar.setLayoutData(gid);
+    }
+
+    /**
+     * Sets the child viewer.  This method should only be called once, after the
+     * viewer has been created.
+     *
+     * @param aViewer the new child viewer
+     */
+    public void setChildTree(TreeViewer aViewer) {
+        // Save viewer.
+        fChildTree = aViewer;
+
+        // Create adapter.
+        adapter = new DrillDownAdapter(fChildTree,imageService);
+        adapter.addNavigationActions(toolBarMgr);
+        toolBarMgr.update(true);
+
+        // Set tree layout.
+        fChildTree.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+        layout();
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillFrame.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillFrame.java
new file mode 100644
index 0000000..1908181
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillFrame.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.List;
+
+/* (non-Javadoc)
+ * A <code>DrillFrame</code> is used to record the input element and
+ * selection state for one frame in a <code>DrillDownTreeViewer</code>.
+ * This class is not intended for use beyond the package.
+ */
+/* package */class DrillFrame {
+    Object fElement;
+
+    Object fPropertyName;
+
+    List fExpansion = null;
+
+    /**
+     * Allocates a new DrillFrame.
+     *
+     * @param oElement the tree input element
+     * @param strPropertyName the visible tree property
+     * @param vExpansion the current expansion state of the tree
+     */
+    public DrillFrame(Object oElement, Object strPropertyName, List vExpansion) {
+        fElement = oElement;
+        fPropertyName = strPropertyName;
+        fExpansion = vExpansion;
+    }
+
+    /**
+     * Compares two Objects for equality.
+     * <p>
+     *
+     * @param   obj   the reference object with which to compare.
+     * @return  <code>true</code> if this object is the same as the obj
+     *          argument; <code>false</code> otherwise.
+     */
+    public boolean equals(Object obj) {
+        // Compare handles.
+        if (this == obj) {
+			return true;
+		}
+
+        // Compare class.
+        if (!(obj instanceof DrillFrame)) {
+			return false;
+		}
+
+        // Compare contents.
+        DrillFrame oOther = (DrillFrame) obj;
+        return ((fElement == oOther.fElement) && (fPropertyName
+                .equals(oOther.fPropertyName)));
+    }
+
+    /**
+     * Returns the input element.
+     *
+     * @return the input element
+     */
+    public Object getElement() {
+        return fElement;
+    }
+
+    /**
+     * Returns the expansion state for a tree.
+     *
+     * @return the expansion state for a tree
+     */
+    public List getExpansion() {
+        return fExpansion;
+    }
+
+    /**
+     * Returns the property name.
+     *
+     * @return the property name
+     */
+    public Object getPropertyName() {
+        return fPropertyName;
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillStack.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillStack.java
new file mode 100644
index 0000000..7e2343c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillStack.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.Stack;
+
+/* (non-Javadoc)
+ * A <code>DrillStack</code> manages a stack of DrillFrames.
+ * This class is not intended for use beyond the package.
+ */
+/* package */class DrillStack {
+    Stack fStack = null;
+
+    /**
+     * Allocates a new DrillStack.
+     */
+    public DrillStack() {
+        reset();
+    }
+
+    /**
+     * Adds a drill frame to the stack.
+     *
+     * @param oRecord the new drill frame
+     */
+    public DrillFrame add(DrillFrame oRecord) {
+        fStack.push(oRecord);
+        return oRecord;
+    }
+
+    /**
+     * Returns true if backward navigation is possible.  This is only true
+     * if the stack size is greater than 0.
+     *
+     * @return true if backward navigation is possible
+     */
+    public boolean canGoBack() {
+        return (fStack.size() > 0);
+    }
+
+    /**
+     * Returns true if "go home" is possible.  This is only true
+     * if the stack size is greater than 0.
+     *
+     * @return true if "go home" is possible
+     */
+    public boolean canGoHome() {
+        return (fStack.size() > 0);
+    }
+
+    /**
+     * Navigate backwards one record.
+     */
+    public DrillFrame goBack() {
+        DrillFrame aFrame = (DrillFrame) fStack.pop();
+        return aFrame;
+    }
+
+    /**
+     * Navigate to the home record.
+     */
+    public DrillFrame goHome() {
+        DrillFrame aFrame = (DrillFrame) fStack.elementAt(0);
+        reset();
+        return aFrame;
+    }
+
+    /**
+     * Clears the navigation stack.
+     */
+    public void reset() {
+        fStack = new Stack();
+    }
+
+    /**
+     * Returns the stack size.
+     *
+     * @return the stack size
+     */
+    public int size() {
+        return fStack.size();
+    }
+
+    /**
+     * Returns the top element on the stack.
+     *
+     * @return the top element on the stack
+     */
+    public DrillFrame top() {
+        return (DrillFrame) fStack.peek();
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ISelectionValidator.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ISelectionValidator.java
new file mode 100644
index 0000000..7bc4f98
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ISelectionValidator.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+/**
+ * For validating selections in some selection dialogs.
+ * <p>
+ * Clients should implement this interface to define specialized selection
+ * validators. 
+ * </p>
+ */
+public interface ISelectionValidator {
+    /**
+     * Returns a string indicating whether the given selection is valid. If the
+     * result is <code>null</code>, the selection is considered to be valid; if the result is
+     * non-empty, it contains the error message to be displayed to the user.
+     *
+     * @param selection the selection to be validated
+     * @return the error message, or <code>null</code> indicating
+     *	that the value is valid
+     */
+    public String isValid(Object selection);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.classpath b/examples/org.eclipse.e4.demo.simpleide.e4editor/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.project b/examples/org.eclipse.e4.demo.simpleide.e4editor/.project
new file mode 100644
index 0000000..060aa8e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.e4editor</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..13c68fb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon May 17 10:02:45 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..9f4cd72
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:05 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.e4editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ebe8e58
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: E4editor
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.e4editor;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.tools.emf.ui;bundle-version="0.9.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.core.resources;bundle-version="3.7.100"
+Service-Component: OSGI-INF/xmiresourcecontextfunction.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/OSGI-INF/xmiresourcecontextfunction.xml b/examples/org.eclipse.e4.demo.simpleide.e4editor/OSGI-INF/xmiresourcecontextfunction.xml
new file mode 100644
index 0000000..647a333
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/OSGI-INF/xmiresourcecontextfunction.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.simpleide.e4editor.xmiresourcecontextfunction">
+   <implementation class="org.eclipse.e4.demo.simpleide.e4editor.XMIResourceFunction"/>
+   <service>
+      <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+   </service>
+   <property name="service.context.key" type="String" value="org.eclipse.e4.tools.emf.ui.common.IModelResource"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/build.properties b/examples/org.eclipse.e4.demo.simpleide.e4editor/build.properties
new file mode 100644
index 0000000..1b0981f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/build.properties
@@ -0,0 +1,6 @@
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               OSGI-INF/xmiresourcecontextfunction.xml,\
+               plugin.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png b/examples/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png
new file mode 100644
index 0000000..3bc0bd3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.e4editor/plugin.xml
new file mode 100644
index 0000000..b39876c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id2"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/src/org/eclipse/e4/demo/simpleide/e4editor/XMIResourceFunction.java b/examples/org.eclipse.e4.demo.simpleide.e4editor/src/org/eclipse/e4/demo/simpleide/e4editor/XMIResourceFunction.java
new file mode 100644
index 0000000..74947ae
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/src/org/eclipse/e4/demo/simpleide/e4editor/XMIResourceFunction.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.e4editor;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.tools.emf.ui.common.IModelResource.ModelListener;
+import org.eclipse.e4.tools.emf.ui.common.XMIModelResource;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+import org.eclipse.emf.common.util.URI;
+
+public class XMIResourceFunction extends ContextFunction {
+	@Override
+	public Object compute(IEclipseContext context) {
+		final MInputPart part = context.get(MInputPart.class);
+		if( part != null ) {
+			final XMIModelResource resource = new XMIModelResource(URI.createPlatformResourceURI(part.getInputURI(),false));
+			resource.addModelListener(new ModelListener() {
+				
+				public void dirtyChanged() {
+					part.setDirty(resource.isDirty());
+				}
+
+				public void commandStackChanged() {
+					
+				}
+			});
+			return resource;			
+		}
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.e4editor/xmi/fragment.e4xmi
new file mode 100644
index 0000000..d300acf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/xmi/fragment.e4xmi
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_Y_hlIHZiEd-iDrIYpK0HDA">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_s3LFAHZiEd-84etnte_XqQ" featurename="editorPartDescriptors" parentElementId="app.simpleide">
+    <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_Vg-BUHZnEd-hBfer1g14pA" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png" contributionURI="bundleclass://org.eclipse.e4.tools.emf.ui/org.eclipse.e4.tools.emf.ui.internal.wbm.ApplicationModelEditor">
+      <fileextensions>e4xmi</fileextensions>
+    </elements>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.classpath b/examples/org.eclipse.e4.demo.simpleide.editor.text/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.project b/examples/org.eclipse.e4.demo.simpleide.editor.text/.project
new file mode 100644
index 0000000..e381f23
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.editor.text</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..16b5b24
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri May 14 19:06:05 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..6ccf2e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:27 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.editor.text/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..fc1bd4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Text
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.editor.text;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.jface.text;bundle-version="3.6.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.editor;bundle-version="1.0.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.e4.ui.di;bundle-version="0.9.0"
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/build.properties b/examples/org.eclipse.e4.demo.simpleide.editor.text/build.properties
new file mode 100644
index 0000000..256e212
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               icons/,\
+               xmi/
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif
new file mode 100644
index 0000000..33be7d8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif
new file mode 100644
index 0000000..7ccc6a7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.editor.text/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id1"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/PlainTextEditor.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/PlainTextEditor.java
new file mode 100644
index 0000000..38f1d72
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/PlainTextEditor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text;
+
+import javax.inject.Inject;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class PlainTextEditor {
+	private IDocumentInput input;
+	
+	@Inject
+	public PlainTextEditor(Composite parent, IDocumentInput input) {
+		this.input = input;
+		parent.setLayout(new FillLayout());
+		
+		int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
+		TextViewer viewer = new TextViewer(parent, styles);
+		viewer.setDocument(input.getDocument());
+	}
+	
+	@Persist
+	public void save() {
+		input.save();
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/XMLTextEditor.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/XMLTextEditor.java
new file mode 100644
index 0000000..79eaa38
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/XMLTextEditor.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text;
+
+import javax.inject.Inject;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.e4.demo.simpleide.editor.text.xml.ColorManager;
+import org.eclipse.e4.demo.simpleide.editor.text.xml.XMLConfiguration;
+import org.eclipse.e4.demo.simpleide.editor.text.xml.XMLPartitionScanner;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.VerticalRuler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class XMLTextEditor {
+	private static final int VERTICAL_RULER_WIDTH = 12;
+	
+	private ColorManager colorManager;
+	
+	private IDocumentInput input;
+
+	@Inject
+	public XMLTextEditor(Composite parent, IDocumentInput input) {
+		this.input = input;
+		parent.setLayout(new FillLayout());
+		
+		colorManager = new ColorManager();
+		VerticalRuler verticalRuler = new VerticalRuler(VERTICAL_RULER_WIDTH);
+		
+		int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
+		SourceViewer viewer = new SourceViewer(parent, verticalRuler, styles);
+		viewer.configure(new XMLConfiguration(colorManager));
+		IDocument document = input.getDocument();
+		IDocumentPartitioner partitioner =
+			new FastPartitioner(
+				new XMLPartitionScanner(),
+				new String[] {
+					XMLPartitionScanner.XML_TAG,
+					XMLPartitionScanner.XML_COMMENT });
+		partitioner.connect(document);
+		document.setDocumentPartitioner(partitioner);
+		viewer.setDocument(document);
+	}
+	
+	@Persist
+	public void save() {
+		System.err.println("Saving ...");
+		input.save();
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/ColorManager.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/ColorManager.java
new file mode 100644
index 0000000..51d5085
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/ColorManager.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+public class ColorManager {
+
+	protected Map<RGB, Color> fColorTable = new HashMap<RGB, Color>(10);
+
+	public void dispose() {
+		Iterator<Color> e = fColorTable.values().iterator();
+		while (e.hasNext())
+			((Color) e.next()).dispose();
+	}
+
+	public Color getColor(RGB rgb) {
+		Color color = (Color) fColorTable.get(rgb);
+		if (color == null) {
+			color = new Color(Display.getCurrent(), rgb);
+			fColorTable.put(rgb, color);
+		}
+		return color;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/IXMLColorConstants.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/IXMLColorConstants.java
new file mode 100644
index 0000000..5e395e8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/IXMLColorConstants.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.swt.graphics.RGB;
+
+public interface IXMLColorConstants {
+	RGB XML_COMMENT = new RGB(128, 0, 0);
+	RGB PROC_INSTR = new RGB(128, 128, 128);
+	RGB STRING = new RGB(0, 128, 0);
+	RGB DEFAULT = new RGB(0, 0, 0);
+	RGB TAG = new RGB(0, 0, 128);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/NonRuleBasedDamagerRepairer.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/NonRuleBasedDamagerRepairer.java
new file mode 100644
index 0000000..f66249c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/NonRuleBasedDamagerRepairer.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.swt.custom.StyleRange;
+
+public class NonRuleBasedDamagerRepairer
+	implements IPresentationDamager, IPresentationRepairer {
+
+	/** The document this object works on */
+	protected IDocument fDocument;
+	/** The default text attribute if non is returned as data by the current token */
+	protected TextAttribute fDefaultTextAttribute;
+	
+	/**
+	 * Constructor for NonRuleBasedDamagerRepairer.
+	 */
+	public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) {
+		Assert.isNotNull(defaultTextAttribute);
+
+		fDefaultTextAttribute = defaultTextAttribute;
+	}
+
+	/**
+	 * @see IPresentationRepairer#setDocument(IDocument)
+	 */
+	public void setDocument(IDocument document) {
+		fDocument = document;
+	}
+
+	/**
+	 * Returns the end offset of the line that contains the specified offset or
+	 * if the offset is inside a line delimiter, the end offset of the next line.
+	 *
+	 * @param offset the offset whose line end offset must be computed
+	 * @return the line end offset for the given offset
+	 * @exception BadLocationException if offset is invalid in the current document
+	 */
+	protected int endOfLineOf(int offset) throws BadLocationException {
+
+		IRegion info = fDocument.getLineInformationOfOffset(offset);
+		if (offset <= info.getOffset() + info.getLength())
+			return info.getOffset() + info.getLength();
+
+		int line = fDocument.getLineOfOffset(offset);
+		try {
+			info = fDocument.getLineInformation(line + 1);
+			return info.getOffset() + info.getLength();
+		} catch (BadLocationException x) {
+			return fDocument.getLength();
+		}
+	}
+
+	/**
+	 * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
+	 */
+	public IRegion getDamageRegion(
+		ITypedRegion partition,
+		DocumentEvent event,
+		boolean documentPartitioningChanged) {
+		if (!documentPartitioningChanged) {
+			try {
+
+				IRegion info =
+					fDocument.getLineInformationOfOffset(event.getOffset());
+				int start = Math.max(partition.getOffset(), info.getOffset());
+
+				int end =
+					event.getOffset()
+						+ (event.getText() == null
+							? event.getLength()
+							: event.getText().length());
+
+				if (info.getOffset() <= end
+					&& end <= info.getOffset() + info.getLength()) {
+					// optimize the case of the same line
+					end = info.getOffset() + info.getLength();
+				} else
+					end = endOfLineOf(end);
+
+				end =
+					Math.min(
+						partition.getOffset() + partition.getLength(),
+						end);
+				return new Region(start, end - start);
+
+			} catch (BadLocationException x) {
+			}
+		}
+
+		return partition;
+	}
+
+	/**
+	 * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+	 */
+	public void createPresentation(
+		TextPresentation presentation,
+		ITypedRegion region) {
+		addRange(
+			presentation,
+			region.getOffset(),
+			region.getLength(),
+			fDefaultTextAttribute);
+	}
+
+	/**
+	 * Adds style information to the given text presentation.
+	 *
+	 * @param presentation the text presentation to be extended
+	 * @param offset the offset of the range to be styled
+	 * @param length the length of the range to be styled
+	 * @param attr the attribute describing the style of the range to be styled
+	 */
+	protected void addRange(
+		TextPresentation presentation,
+		int offset,
+		int length,
+		TextAttribute attr) {
+		if (attr != null)
+			presentation.addStyleRange(
+				new StyleRange(
+					offset,
+					length,
+					attr.getForeground(),
+					attr.getBackground(),
+					attr.getStyle()));
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/TagRule.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/TagRule.java
new file mode 100644
index 0000000..eb850b9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/TagRule.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+
+public class TagRule extends MultiLineRule {
+
+	public TagRule(IToken token) {
+		super("<", ">", token);
+	}
+	protected boolean sequenceDetected(
+		ICharacterScanner scanner,
+		char[] sequence,
+		boolean eofAllowed) {
+		int c = scanner.read();
+		if (sequence[0] == '<') {
+			if (c == '?') {
+				// processing instruction - abort
+				scanner.unread();
+				return false;
+			}
+			if (c == '!') {
+				scanner.unread();
+				// comment - abort
+				return false;
+			}
+		} else if (sequence[0] == '>') {
+			scanner.unread();
+		}
+		return super.sequenceDetected(scanner, sequence, eofAllowed);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLConfiguration.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLConfiguration.java
new file mode 100644
index 0000000..3ed744c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLConfiguration.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class XMLConfiguration extends SourceViewerConfiguration {
+	private XMLDoubleClickStrategy doubleClickStrategy;
+	private XMLTagScanner tagScanner;
+	private XMLScanner scanner;
+	private ColorManager colorManager;
+
+	public XMLConfiguration(ColorManager colorManager) {
+		this.colorManager = colorManager;
+	}
+	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+		return new String[] {
+			IDocument.DEFAULT_CONTENT_TYPE,
+			XMLPartitionScanner.XML_COMMENT,
+			XMLPartitionScanner.XML_TAG };
+	}
+	public ITextDoubleClickStrategy getDoubleClickStrategy(
+		ISourceViewer sourceViewer,
+		String contentType) {
+		if (doubleClickStrategy == null)
+			doubleClickStrategy = new XMLDoubleClickStrategy();
+		return doubleClickStrategy;
+	}
+
+	protected XMLScanner getXMLScanner() {
+		if (scanner == null) {
+			scanner = new XMLScanner(colorManager);
+			scanner.setDefaultReturnToken(
+				new Token(
+					new TextAttribute(
+						colorManager.getColor(IXMLColorConstants.DEFAULT))));
+		}
+		return scanner;
+	}
+	protected XMLTagScanner getXMLTagScanner() {
+		if (tagScanner == null) {
+			tagScanner = new XMLTagScanner(colorManager);
+			tagScanner.setDefaultReturnToken(
+				new Token(
+					new TextAttribute(
+						colorManager.getColor(IXMLColorConstants.TAG))));
+		}
+		return tagScanner;
+	}
+
+	public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+		PresentationReconciler reconciler = new PresentationReconciler();
+
+		DefaultDamagerRepairer dr =
+			new DefaultDamagerRepairer(getXMLTagScanner());
+		reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG);
+		reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG);
+
+		dr = new DefaultDamagerRepairer(getXMLScanner());
+		reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+		reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+		NonRuleBasedDamagerRepairer ndr =
+			new NonRuleBasedDamagerRepairer(
+				new TextAttribute(
+					colorManager.getColor(IXMLColorConstants.XML_COMMENT)));
+		reconciler.setDamager(ndr, XMLPartitionScanner.XML_COMMENT);
+		reconciler.setRepairer(ndr, XMLPartitionScanner.XML_COMMENT);
+
+		return reconciler;
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLDoubleClickStrategy.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLDoubleClickStrategy.java
new file mode 100644
index 0000000..411b570
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLDoubleClickStrategy.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+
+public class XMLDoubleClickStrategy implements ITextDoubleClickStrategy {
+	protected ITextViewer fText;
+
+	public void doubleClicked(ITextViewer part) {
+		int pos = part.getSelectedRange().x;
+
+		if (pos < 0)
+			return;
+
+		fText = part;
+
+		if (!selectComment(pos)) {
+			selectWord(pos);
+		}
+	}
+	protected boolean selectComment(int caretPos) {
+		IDocument doc = fText.getDocument();
+		int startPos, endPos;
+
+		try {
+			int pos = caretPos;
+			char c = ' ';
+
+			while (pos >= 0) {
+				c = doc.getChar(pos);
+				if (c == '\\') {
+					pos -= 2;
+					continue;
+				}
+				if (c == Character.LINE_SEPARATOR || c == '\"')
+					break;
+				--pos;
+			}
+
+			if (c != '\"')
+				return false;
+
+			startPos = pos;
+
+			pos = caretPos;
+			int length = doc.getLength();
+			c = ' ';
+
+			while (pos < length) {
+				c = doc.getChar(pos);
+				if (c == Character.LINE_SEPARATOR || c == '\"')
+					break;
+				++pos;
+			}
+			if (c != '\"')
+				return false;
+
+			endPos = pos;
+
+			int offset = startPos + 1;
+			int len = endPos - offset;
+			fText.setSelectedRange(offset, len);
+			return true;
+		} catch (BadLocationException x) {
+		}
+
+		return false;
+	}
+	protected boolean selectWord(int caretPos) {
+
+		IDocument doc = fText.getDocument();
+		int startPos, endPos;
+
+		try {
+
+			int pos = caretPos;
+			char c;
+
+			while (pos >= 0) {
+				c = doc.getChar(pos);
+				if (!Character.isJavaIdentifierPart(c))
+					break;
+				--pos;
+			}
+
+			startPos = pos;
+
+			pos = caretPos;
+			int length = doc.getLength();
+
+			while (pos < length) {
+				c = doc.getChar(pos);
+				if (!Character.isJavaIdentifierPart(c))
+					break;
+				++pos;
+			}
+
+			endPos = pos;
+			selectRange(startPos, endPos);
+			return true;
+
+		} catch (BadLocationException x) {
+		}
+
+		return false;
+	}
+
+	private void selectRange(int startPos, int stopPos) {
+		int offset = startPos + 1;
+		int length = stopPos - offset;
+		fText.setSelectedRange(offset, length);
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLPartitionScanner.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLPartitionScanner.java
new file mode 100644
index 0000000..a82d923
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLPartitionScanner.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.Token;
+
+public class XMLPartitionScanner extends RuleBasedPartitionScanner {
+	public final static String XML_COMMENT = "__xml_comment";
+	public final static String XML_TAG = "__xml_tag";
+
+	public XMLPartitionScanner() {
+
+		IToken xmlComment = new Token(XML_COMMENT);
+		IToken tag = new Token(XML_TAG);
+
+		IPredicateRule[] rules = new IPredicateRule[2];
+
+		rules[0] = new MultiLineRule("<!--", "-->", xmlComment);
+		rules[1] = new TagRule(tag);
+
+		setPredicateRules(rules);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLScanner.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLScanner.java
new file mode 100644
index 0000000..6e08811
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLScanner.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+public class XMLScanner extends RuleBasedScanner {
+
+	public XMLScanner(ColorManager manager) {
+		IToken procInstr =
+			new Token(
+				new TextAttribute(
+					manager.getColor(IXMLColorConstants.PROC_INSTR)));
+
+		IRule[] rules = new IRule[2];
+		//Add rule for processing instructions
+		rules[0] = new SingleLineRule("<?", "?>", procInstr);
+		// Add generic whitespace rule.
+		rules[1] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+		setRules(rules);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLTagScanner.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLTagScanner.java
new file mode 100644
index 0000000..bbd7a0e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLTagScanner.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+public class XMLTagScanner extends RuleBasedScanner {
+
+	public XMLTagScanner(ColorManager manager) {
+		IToken string =
+			new Token(
+				new TextAttribute(manager.getColor(IXMLColorConstants.STRING)));
+
+		IRule[] rules = new IRule[3];
+
+		// Add rule for double quotes
+		rules[0] = new SingleLineRule("\"", "\"", string, '\\');
+		// Add a rule for single quotes
+		rules[1] = new SingleLineRule("'", "'", string, '\\');
+		// Add generic whitespace rule.
+		rules[2] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+		setRules(rules);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLWhitespaceDetector.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLWhitespaceDetector.java
new file mode 100644
index 0000000..0bdd6ef
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLWhitespaceDetector.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+public class XMLWhitespaceDetector implements IWhitespaceDetector {
+
+	public boolean isWhitespace(char c) {
+		return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.editor.text/xmi/fragment.e4xmi
new file mode 100644
index 0000000..b327453
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/xmi/fragment.e4xmi
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_jwyiYHieEd-X-LLzc-gFOA">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_phxCgHieEd-X-LLzc-gFOA" featurename="editorPartDescriptors" parentElementId="app.simpleide">
+    <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_7qZb0HieEd-ivry1rGVmOg" label="Text Editor" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.editor.text/org.eclipse.e4.demo.simpleide.editor.text.PlainTextEditor">
+      <fileextensions>txt</fileextensions>
+    </elements>
+    <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_ILaFUHifEd-ivry1rGVmOg" label="XML Editor" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.editor.text/org.eclipse.e4.demo.simpleide.editor.text.XMLTextEditor">
+      <fileextensions>xml</fileextensions>
+    </elements>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.classpath b/examples/org.eclipse.e4.demo.simpleide.editor/.classpath
new file mode 100644
index 0000000..304e861
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.project b/examples/org.eclipse.e4.demo.simpleide.editor/.project
new file mode 100644
index 0000000..2fd84c1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.editor</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ba74073
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri May 14 19:08:27 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..861792a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:17 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..48058cb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.editor;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.e4.ui.model.workbench;visibility:=reexport,
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.jface.text;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1"
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.e4.core.contexts
+Export-Package: org.eclipse.e4.demo.simpleide.editor
+Service-Component: OSGI-INF/documentInputProviderFunction.xml
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/OSGI-INF/documentInputProviderFunction.xml b/examples/org.eclipse.e4.demo.simpleide.editor/OSGI-INF/documentInputProviderFunction.xml
new file mode 100644
index 0000000..7d30685
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/OSGI-INF/documentInputProviderFunction.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.editor.documentInputProviderFunction">
+   <implementation class="org.eclipse.e4.demo.simpleide.editor.internal.IDocumentInputProviderFunction"/>
+   <service>
+      <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+   </service>
+   <property name="service.context.key" type="String" value="org.eclipse.e4.demo.simpleide.editor.IDocumentInput"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/build.properties b/examples/org.eclipse.e4.demo.simpleide.editor/build.properties
new file mode 100644
index 0000000..186d187
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/build.properties
@@ -0,0 +1,8 @@
+bin.includes = .,\
+               META-INF/,\
+               OSGI-INF/documentInputProviderFunction.xml,\
+               plugin.xml,\
+               xmi/
+output.. = bin/
+jars.compile.order = .
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.editor/plugin.xml
new file mode 100644
index 0000000..b39876c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id2"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IDocumentInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IDocumentInput.java
new file mode 100644
index 0000000..a65e480
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IDocumentInput.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor;
+
+import org.eclipse.jface.text.IDocument;
+
+public interface IDocumentInput extends IInput {
+	public IDocument getDocument();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IInput.java
new file mode 100644
index 0000000..9546d41
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IInput.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor;
+
+import org.eclipse.core.runtime.IStatus;
+
+public interface IInput {
+	public static final String DIRTY = IInput.class.getName() + ".dirty";
+	
+	public interface Listener {
+		public void propertyChanged(String property, Object oldValue, Object newValue);
+	}
+	
+	public void addListener(Listener listener);
+	public void removeListener(Listener listener);
+	
+	public IStatus save();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/handler/OpenEditor.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/handler/OpenEditor.java
new file mode 100644
index 0000000..e812c1c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/handler/OpenEditor.java
@@ -0,0 +1,35 @@
+package org.eclipse.e4.demo.simpleide.editor.handler;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
+
+public class OpenEditor {
+	
+	@Execute
+	public void open(
+			IFile file,
+			MApplication application, 
+			MEditorPartDescriptor model, 
+			EModelService modelService, 
+			EPartService partService) {
+		MPartStack stack = (MPartStack) modelService.find("org.eclipse.e4.primaryDataStack", application);
+		
+		MInputPart part = MBasicFactory.INSTANCE.createInputPart();
+		part.setContributionURI(model.getContributionURI());
+		part.setInputURI(file.getFullPath().toString());
+		part.setIconURI(model.getIconURI());
+		part.setLabel(file.getName());
+		part.setTooltip(file.getFullPath().toString());
+		part.setCloseable(true);
+		stack.getChildren().add(part);
+		partService.showPart(part, PartState.ACTIVATE);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/AbstractInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/AbstractInput.java
new file mode 100644
index 0000000..0bf71db
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/AbstractInput.java
@@ -0,0 +1,34 @@
+package org.eclipse.e4.demo.simpleide.editor.internal;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.e4.demo.simpleide.editor.IInput;
+
+public abstract class AbstractInput implements IInput {
+	private ListenerList listeners = new ListenerList();
+	private boolean dirty = false;
+	
+	public void addListener(Listener listener) {
+		listeners.add(listener);
+	}
+
+	public void removeListener(Listener listener) {
+		listeners.remove(listener);
+	}
+	
+	private void fireDirtyChange(boolean oldValue, boolean newValue) {
+		this.dirty = newValue;
+		for( Object l : listeners.getListeners() ) {
+			((Listener)l).propertyChanged(DIRTY, oldValue, newValue);
+		}
+	}
+	
+	protected void setDirty(boolean dirty) {
+		if( dirty != this.dirty ) {
+			fireDirtyChange(this.dirty, this.dirty = dirty);
+		}
+	}
+	
+	protected boolean isDirty() {
+		return dirty;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/FileDocumentInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/FileDocumentInput.java
new file mode 100644
index 0000000..93729c4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/FileDocumentInput.java
@@ -0,0 +1,144 @@
+package org.eclipse.e4.demo.simpleide.editor.internal;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+
+public class FileDocumentInput extends AbstractInput implements IDocumentInput {
+	private IFile file;
+	private IDocument document;
+
+	private static final int DEFAULT_FILE_SIZE = 15 * 1024;
+
+	public FileDocumentInput(IFile file) {
+		this.file = file;
+	}
+
+	public IStatus save() {
+		System.err.println("Starting save");
+		
+		String encoding = null;
+		try {
+			encoding = file.getCharset();
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+		}
+
+		if (encoding == null)
+			encoding = "UTF-8";
+		
+		Charset charset= Charset.forName(encoding);
+		CharsetEncoder encoder = charset.newEncoder();
+		
+		byte[] bytes;
+		ByteBuffer byteBuffer;
+		try {
+			byteBuffer = encoder.encode(CharBuffer.wrap(document.get()));
+			if (byteBuffer.hasArray())
+				bytes= byteBuffer.array();
+			else {
+				bytes= new byte[byteBuffer.limit()];
+				byteBuffer.get(bytes);
+			}
+			ByteArrayInputStream stream= new ByteArrayInputStream(bytes, 0, byteBuffer.limit());
+			
+			file.setContents(stream, true, true, null);
+			setDirty(false);
+			
+		} catch (CharacterCodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (CoreException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		System.err.println("Saving done");
+		
+		return null;
+	}
+
+	public IDocument getDocument() {
+		if (document == null) {
+			Document document = new Document();
+			Reader in = null;
+
+			InputStream contentStream = null;
+			try {
+				contentStream = file.getContents();
+			} catch (CoreException e1) {
+				// TODO Auto-generated catch block
+				e1.printStackTrace();
+			}
+
+			if (contentStream == null) {
+				return null;
+			}
+
+			try {
+				String encoding = null;
+				try {
+					encoding = file.getCharset();
+				} catch (Exception e) {
+					// TODO: handle exception
+					e.printStackTrace();
+				}
+
+				if (encoding == null)
+					encoding = "UTF-8";
+
+				in = new BufferedReader(new InputStreamReader(contentStream,
+						encoding), DEFAULT_FILE_SIZE);
+				StringBuffer buffer = new StringBuffer(DEFAULT_FILE_SIZE);
+				char[] readBuffer = new char[2048];
+				int n = in.read(readBuffer);
+				while (n > 0) {
+					buffer.append(readBuffer, 0, n);
+					n = in.read(readBuffer);
+				}
+
+				document.set(buffer.toString());
+				this.document = document;
+				document.addDocumentListener(new IDocumentListener() {
+					
+					public void documentChanged(DocumentEvent event) {
+						setDirty(true);
+					}
+					
+					public void documentAboutToBeChanged(DocumentEvent event) {
+						
+					}
+				});
+			} catch (IOException x) {
+				x.printStackTrace();
+			} finally {
+				try {
+					if (in != null)
+						in.close();
+					else
+						contentStream.close();
+				} catch (IOException x) {
+				}
+			}
+		}
+
+		return document;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/IDocumentInputProviderFunction.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/IDocumentInputProviderFunction.java
new file mode 100644
index 0000000..55f1c41
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/IDocumentInputProviderFunction.java
@@ -0,0 +1,37 @@
+package org.eclipse.e4.demo.simpleide.editor.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.editor.IInput;
+import org.eclipse.e4.demo.simpleide.editor.IInput.Listener;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+
+public class IDocumentInputProviderFunction extends ContextFunction {
+
+	@Override
+	public Object compute(IEclipseContext context) {
+		final MInputPart inputPart = context.get(MInputPart.class);
+		
+		IWorkspace workspace = context.get(IWorkspace.class);
+		
+		String uri = inputPart.getInputURI();
+		Path p = new Path(uri);
+		IFile file = workspace.getRoot().getFile(p);
+		FileDocumentInput input = new FileDocumentInput(file);
+		
+		input.addListener(new Listener() {
+			
+			public void propertyChanged(String property, Object oldValue,
+					Object newValue) {
+				if( IInput.DIRTY == property ) {
+					inputPart.setDirty((Boolean)newValue);
+				}
+			}
+		});
+		
+		return input;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.editor/xmi/fragment.e4xmi
new file mode 100644
index 0000000..0422960
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/xmi/fragment.e4xmi
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_tkhKcHiXEd-pEoU9D4-ITQ">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_xOhvUHidEd-X-LLzc-gFOA" featurename="handlers" parentElementId="app.simpleide">
+    <elements xsi:type="commands:Handler" xmi:id="_CDBAMHieEd-X-LLzc-gFOA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.editor/org.eclipse.e4.demo.simpleide.editor.handler.OpenEditor" command="_9a6zsHidEd-X-LLzc-gFOA"/>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_2pDeUHidEd-X-LLzc-gFOA" featurename="commands" parentElementId="app.simpleide">
+    <elements xsi:type="commands:Command" xmi:id="_9a6zsHidEd-X-LLzc-gFOA" elementId="simpleide.command.openeditor" commandName="Open Editor"/>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.classpath b/examples/org.eclipse.e4.demo.simpleide.iconview/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.project b/examples/org.eclipse.e4.demo.simpleide.iconview/.project
new file mode 100644
index 0000000..20df9e3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.iconview</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..8952d64
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon May 24 16:33:09 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..d33d0a8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:37 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.iconview/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ce8a3cf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Iconview
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.iconview;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.nebula.widgets.gallery;bundle-version="0.5.3",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.jface.databinding;bundle-version="1.4.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.core.jobs;bundle-version="3.5.0",
+ org.eclipse.core.contenttype;bundle-version="3.4.100",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1"
+Import-Package: javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/build.properties b/examples/org.eclipse.e4.demo.simpleide.iconview/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png b/examples/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png
new file mode 100644
index 0000000..052b336
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.iconview/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id1"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/CustomGalleryItemRenderer.java b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/CustomGalleryItemRenderer.java
new file mode 100644
index 0000000..43ee6bc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/CustomGalleryItemRenderer.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.iconview;
+
+import org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.nebula.widgets.gallery.RendererHelper;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+
+public class CustomGalleryItemRenderer extends
+		AbstractGalleryItemRenderer {
+	@Override
+	public void draw(GC gc, GalleryItem item, int index, int x, int y,
+			int width, int height) {
+		Image image = item.getImage();
+		gc.setFont(item.getFont());
+		
+		int padding = 5;
+		
+		int maxWidth = width - padding * 2;
+		int maxHeight = height - padding * 2;
+		
+		if( isSelected() ) {
+			Color bg = gc.getBackground();
+			gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION));
+			gc.fillRoundRectangle(x, y, width, height, 5, 5);
+			gc.setBackground(bg);
+		}
+		
+		int maxImageHeight = maxHeight - padding -  gc.getFontMetrics().getHeight();
+		
+		String text = RendererHelper.createLabel(item.getText(), gc, maxWidth);
+		
+		int imageWidth = image.getBounds().width;
+		int imageHeight = image.getBounds().height;
+		
+		Point imageSize;
+		
+		if( imageWidth <= maxWidth && imageHeight <= maxImageHeight ) {
+			imageSize = new Point(imageWidth, imageHeight);
+		} else {
+			imageSize = RendererHelper.getBestSize(imageWidth, imageHeight, maxWidth, maxImageHeight);				
+		}
+
+		int imageX = x + padding;
+		int imageY = y + padding;
+		
+		if( imageSize.x < maxWidth ) {
+			imageX = x + width / 2 - imageSize.x / 2;
+		}
+		
+		gc.drawImage(image, imageX, imageY);
+		
+		int textX = x + padding;
+		int textY = y + padding + imageSize.y + padding;
+		Point textSize = gc.textExtent(text);
+		
+		if( textSize.x < maxWidth ) {
+			textX = x + width / 2 - textSize.x / 2;
+		}
+		
+		gc.drawText(text, textX, textY, true);
+	}
+
+	@Override
+	public void dispose() {
+		// TODO Auto-generated method stub
+		
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/IconView.java b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/IconView.java
new file mode 100644
index 0000000..d87c96c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/IconView.java
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.iconview;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.modeling.IPartListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.nebula.jface.galleryviewer.GalleryTreeViewer;
+import org.eclipse.nebula.widgets.gallery.NoGroupRenderer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class IconView {
+
+	private IResourceChangeListener resourceListener = new IResourceChangeListener() {
+		public void resourceChanged(IResourceChangeEvent event) {
+			if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+				try {
+					event.getDelta().accept(new IResourceDeltaVisitor() {
+						public boolean visit(IResourceDelta delta)
+								throws CoreException {
+							if (delta.getKind() == IResourceDelta.ADDED) {
+								handleChange(delta.getResource(), delta
+										.getResource().getParent(), true);
+							} else if (delta.getKind() == IResourceDelta.REMOVED) {
+								handleChange(delta.getResource(), delta
+										.getResource().getParent(), false);
+							}
+							return true;
+						}
+
+						private void handleChange(final IResource resource,
+								final IContainer parent, final boolean added) {
+							if (parent == container) {
+								if( visible ) {
+									if (added) {
+										isImageFile(resource);
+										viewer.add(null, resource);
+									} else {
+										viewer.remove(resource);
+										Image image = imageMap.remove(resource);
+										if (image != null) {
+											image.dispose();
+										}
+									}									
+								} else {
+									needsupdate = true;
+								}
+							}
+						}
+					});
+				} catch (CoreException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+	};
+
+	private ITreeContentProvider contentProvider = new ITreeContentProvider() {
+		private List<IResource> input = new ArrayList<IResource>();
+		private String root = "Elements";
+		
+		@SuppressWarnings("unchecked")
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			this.input = (List<IResource>) newInput;
+		}
+		
+		public void dispose() {
+			
+		}
+		
+		public boolean hasChildren(Object element) {
+			return root == element;
+		}
+		
+		public Object getParent(Object element) {
+			return root;
+		}
+		
+		public Object[] getElements(Object inputElement) {
+			return new Object [] {root};
+		}
+		
+		public Object[] getChildren(Object parentElement) {
+			return input.toArray();
+		}
+	};
+	
+	private IPartListener partListener = new IPartListener() {
+		
+		public void partVisible(MPart part) {
+			if( ! visible && part == IconView.this.part ) {
+				visible = true;
+				if( needsupdate ) {
+					refreshViewer();	
+				}
+			}
+		}
+		
+		public void partHidden(MPart part) {
+			visible = false;
+		}
+		
+		public void partDeactivated(MPart part) {
+			
+		}
+		
+		public void partBroughtToTop(MPart part) {
+			if( ! visible && part == IconView.this.part ) {
+				visible = true;
+				if( needsupdate ) {
+					refreshViewer();	
+				}
+			}
+		}
+		
+		public void partActivated(MPart part) {
+		}
+	};
+	
+	private GalleryTreeViewer viewer;
+	private IContainer container;
+	private IWorkspace workspace;
+	private boolean visible = true;
+	private boolean needsupdate = false;
+	
+	private Map<IResource, Image> imageMap = new HashMap<IResource, Image>();
+	
+	private MPart part;
+	private EPartService partService;
+	
+	@Inject
+	public IconView(Composite composite, EPartService partService, MPart part, IWorkspace workspace) {
+		composite.setLayout(new FillLayout());
+		this.partService = partService;
+		this.part = part;
+		viewer = new GalleryTreeViewer(composite, SWT.MULTI | SWT.V_SCROLL);
+		viewer.getGallery().setItemRenderer(new CustomGalleryItemRenderer());
+		partService.addPartListener(partListener);
+		
+		NoGroupRenderer renderer = new NoGroupRenderer();
+		renderer.setItemHeight(50);
+		
+		viewer.getGallery().setGroupRenderer(renderer);
+		viewer.setContentProvider(contentProvider);
+		
+		viewer.setLabelProvider(new LabelProvider() {
+			@Override
+			public Image getImage(Object element) {
+				if( element instanceof IFile ) {
+					Image image = imageMap.get(element);
+
+					if (image == null) {
+						image = loadImage((IFile) element);
+						imageMap.put((IResource) element, image);
+					}
+
+					return image;					
+				}
+				return super.getImage(element);
+			}
+
+			@Override
+			public String getText(Object element) {
+				if( element instanceof IFile ) {
+					IFile resource = (IFile) element;
+					return resource.getName();	
+				}
+				return super.getText(element);
+			}
+		});
+		this.workspace = workspace;
+		this.workspace.addResourceChangeListener(resourceListener);
+	}
+
+	private Image loadImage(final IFile file) {
+		InputStream contents;
+		try {
+			contents = file.getContents();
+			try {
+				ImageData imageData = new ImageData(contents);
+				Point size = getBestSize(imageData.width, imageData.height, 16,
+						16);
+				ImageData scaled = imageData.scaledTo(size.x, size.y);
+				return new Image(viewer.getControl().getDisplay(), scaled);
+			} catch (Exception e) {
+				// TODO: handle exception
+				e.printStackTrace();
+			}
+		} catch (Exception e) {
+			// TODO: handle exception
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+
+	private Point getBestSize(int originalX, int originalY, int maxX, int maxY) {
+		double widthRatio = (double) originalX / (double) maxX;
+		double heightRatio = (double) originalY / (double) maxY;
+
+		double bestRatio = widthRatio > heightRatio ? widthRatio : heightRatio;
+
+		int newWidth = (int) ((double) originalX / bestRatio);
+		int newHeight = (int) ((double) originalY / bestRatio);
+
+		return new Point(newWidth, newHeight);
+	}
+
+	@PreDestroy
+	void dispose() {
+		this.workspace.removeResourceChangeListener(resourceListener);
+		this.partService.removePartListener(partListener);
+	}
+
+	private boolean isImageFile(IResource resource) {
+		if (resource.getType() == IResource.FILE) {
+			IFile file = (IFile) resource;
+			String extension = file.getFileExtension();
+			if (extension != null
+					&& ("png".equalsIgnoreCase(extension)
+							|| "jpg".equalsIgnoreCase(extension) || "gif"
+							.equalsIgnoreCase(extension))) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	@Inject
+	void setFolder(
+			@Named(IServiceConstants.SELECTION) @Optional IContainer container) {
+		this.container = container;
+//FIXME Need to investigate		if( visible ) {
+			refreshViewer();	
+//		} else {
+//			needsupdate = true;
+//		}
+	}
+
+	private void refreshViewer() {
+		Map<IResource, Image> imageMap = this.imageMap;
+		this.imageMap = new HashMap<IResource, Image>();
+		
+		final List<IResource> input = new ArrayList<IResource>();
+		if (container != null) {
+			try {
+				container.accept(new IResourceVisitor() {
+
+					public boolean visit(IResource resource)
+							throws CoreException {
+						if (resource.equals(IconView.this.container)) {
+							return true;
+						} else if (isImageFile(resource)) {
+							input.add(resource);
+						}
+
+						return false;
+					}
+				});
+			} catch (CoreException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}			
+		}
+		
+		viewer.setInput(input);
+		
+		for (Image img : imageMap.values()) {
+			img.dispose();
+		}
+		needsupdate = false;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.iconview/xmi/fragment.e4xmi
new file mode 100644
index 0000000..4c36784
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/xmi/fragment.e4xmi
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/descriptor/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_DxU0wHihEd-WTYrypQ0Yjg">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_GGkN0HihEd-WTYrypQ0Yjg" featurename="descriptors" parentElementId="app.simpleide">
+    <elements xsi:type="basic:PartDescriptor" xmi:id="_W-aUsHihEd-1hY0DgxUB9A" label="Icon Folder View" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png" elementId="simpleide.descriptors.iconview" category="org.eclipse.e4.secondaryDataStack" closeable="true" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.iconview/org.eclipse.e4.demo.simpleide.iconview.IconView">
+      <tags>View</tags>
+      <tags>categoryTag:Utilities</tags>
+    </elements>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.classpath b/examples/org.eclipse.e4.demo.simpleide.jdt/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.project b/examples/org.eclipse.e4.demo.simpleide.jdt/.project
new file mode 100644
index 0000000..e2ea6f5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.jdt</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a43bb60
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sun May 16 13:44:52 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..43a4b20
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:46 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.jdt/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0039a4b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Jdt
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.jdt;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.jdt.core;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.editor;bundle-version="1.0.0",
+ org.eclipse.jface.text;bundle-version="3.6.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.outline;bundle-version="1.0.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.e4.ui.di;bundle-version="0.9.0"
+Import-Package: javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0",
+ org.eclipse.core.runtime.jobs
+Service-Component: OSGI-INF/jdtProjectService.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/OSGI-INF/jdtProjectService.xml b/examples/org.eclipse.e4.demo.simpleide.jdt/OSGI-INF/jdtProjectService.xml
new file mode 100644
index 0000000..75728fd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/OSGI-INF/jdtProjectService.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.simpleide.jdt.jdtProjectService">
+   <implementation class="org.eclipse.e4.demo.simpleide.jdt.internal.JDTProjectService"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.simpleide.services.IProjectService"/>
+   </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/build.properties b/examples/org.eclipse.e4.demo.simpleide.jdt/build.properties
new file mode 100644
index 0000000..96be7c8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/build.properties
@@ -0,0 +1,8 @@
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               OSGI-INF/jdtProjectService.xml,\
+               icons/,\
+               xmi/
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif
new file mode 100644
index 0000000..435d62e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif
new file mode 100644
index 0000000..15535f5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_alt_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_alt_obj.gif
new file mode 100644
index 0000000..f47bbfc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_alt_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_default_obj.gif
new file mode 100644
index 0000000..9a88459
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_obj.gif
new file mode 100644
index 0000000..435d62e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_private_obj.gif
new file mode 100644
index 0000000..ac01dd2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_protected_obj.gif
new file mode 100644
index 0000000..63c8abf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_obj.gif
new file mode 100644
index 0000000..562d6d4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_src_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_src_obj.gif
new file mode 100644
index 0000000..dd2e028
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_src_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_default_obj.gif
new file mode 100644
index 0000000..4244a7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classf_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classf_obj.gif
new file mode 100644
index 0000000..365e372
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classf_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classfo_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classfo_obj.gif
new file mode 100644
index 0000000..f1ee8cf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classfo_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cprj_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cprj_obj.gif
new file mode 100755
index 0000000..6052a86
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cprj_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_fldr_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_fldr_obj.gif
new file mode 100644
index 0000000..989b5bf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_fldr_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_obj.gif
new file mode 100644
index 0000000..c88284a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_alt_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_alt_obj.gif
new file mode 100644
index 0000000..f470d4c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_alt_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_default_obj.gif
new file mode 100644
index 0000000..e6f557b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_obj.gif
new file mode 100644
index 0000000..15535f5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_private_obj.gif
new file mode 100644
index 0000000..4d83959
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_protected_obj.gif
new file mode 100644
index 0000000..834aa85
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_default_obj.gif
new file mode 100644
index 0000000..6929d3d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_private_obj.gif
new file mode 100644
index 0000000..1fe064e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_protected_obj.gif
new file mode 100644
index 0000000..3377b1e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_public_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_public_obj.gif
new file mode 100644
index 0000000..d4cb425
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_public_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/imp_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/imp_obj.gif
new file mode 100644
index 0000000..9e44ce5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/imp_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/impc_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/impc_obj.gif
new file mode 100644
index 0000000..ea94702
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/impc_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_default_obj.gif
new file mode 100644
index 0000000..4244a7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_private_obj.gif
new file mode 100644
index 0000000..7392f19
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_protected_obj.gif
new file mode 100644
index 0000000..5105577
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_public_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_public_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_public_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_default_obj.gif
new file mode 100644
index 0000000..ab1b576
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_private_obj.gif
new file mode 100644
index 0000000..a1cbff3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_protected_obj.gif
new file mode 100644
index 0000000..f58eef0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_public_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_public_obj.gif
new file mode 100644
index 0000000..2ebc46e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_public_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_default_obj.gif
new file mode 100644
index 0000000..ab1b576
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_obj.gif
new file mode 100644
index 0000000..2ebc46e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/intf_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/intf_obj.gif
new file mode 100644
index 0000000..7d7df9e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/intf_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_l_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_l_obj.gif
new file mode 100644
index 0000000..c026f01
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_l_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_lsrc_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_lsrc_obj.gif
new file mode 100644
index 0000000..3635997
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_lsrc_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_obj.gif
new file mode 100644
index 0000000..c026f01
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_src_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_src_obj.gif
new file mode 100644
index 0000000..3635997
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_src_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/java_model_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/java_model_obj.gif
new file mode 100644
index 0000000..8c8a7ea
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/java_model_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jcu_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jcu_obj.gif
new file mode 100644
index 0000000..200e5ed
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jcu_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/localvariable_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/localvariable_obj.gif
new file mode 100644
index 0000000..8adce95
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/localvariable_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methdef_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methdef_obj.gif
new file mode 100644
index 0000000..f4a1ea1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methdef_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpri_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpri_obj.gif
new file mode 100644
index 0000000..2988716
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpri_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpro_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpro_obj.gif
new file mode 100644
index 0000000..563743d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpro_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpub_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpub_obj.gif
new file mode 100644
index 0000000..7d24707
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpub_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/package_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/package_obj.gif
new file mode 100644
index 0000000..131c28d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/package_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packagefolder_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packagefolder_obj.gif
new file mode 100644
index 0000000..fca9c53
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packagefolder_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packd_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packd_obj.gif
new file mode 100644
index 0000000..2556b45
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packd_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/prj_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/prj_obj.gif
new file mode 100755
index 0000000..a4ea580
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/prj_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/typevariable_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/typevariable_obj.gif
new file mode 100644
index 0000000..d4848c0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/typevariable_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/unknown_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/unknown_obj.gif
new file mode 100644
index 0000000..7d988f9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/unknown_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/abstract_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/abstract_co.gif
new file mode 100644
index 0000000..533acc4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/abstract_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/constr_ovr.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/constr_ovr.gif
new file mode 100644
index 0000000..3977bc0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/constr_ovr.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/deprecated.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/deprecated.gif
new file mode 100644
index 0000000..d03b6a9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/deprecated.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/error_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/error_co.gif
new file mode 100644
index 0000000..119dccc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/error_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/final_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/final_co.gif
new file mode 100644
index 0000000..01c580d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/final_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/implm_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/implm_co.gif
new file mode 100644
index 0000000..7766c9d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/implm_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/over_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/over_co.gif
new file mode 100644
index 0000000..8533e2e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/over_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/run_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/run_co.gif
new file mode 100644
index 0000000..13077f9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/run_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/static_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/static_co.gif
new file mode 100644
index 0000000..499664d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/static_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_impl.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_impl.gif
new file mode 100644
index 0000000..2a0a385
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_impl.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_over.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_over.gif
new file mode 100644
index 0000000..52c958a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_over.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/synch_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/synch_co.gif
new file mode 100644
index 0000000..5893bda
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/synch_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/transient_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/transient_co.gif
new file mode 100644
index 0000000..2a386de
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/transient_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/volatile_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/volatile_co.gif
new file mode 100644
index 0000000..4345539
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/volatile_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/warning_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/warning_co.gif
new file mode 100644
index 0000000..ee2dac4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/warning_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif
new file mode 100644
index 0000000..2ebc46e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif
new file mode 100644
index 0000000..200e5ed
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/newjprj_wiz.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/newjprj_wiz.gif
new file mode 100644
index 0000000..bc85aaf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/newjprj_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_default_obj.gif
new file mode 100644
index 0000000..4244a7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/imp_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/imp_obj.gif
new file mode 100644
index 0000000..9e44ce5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/imp_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/impc_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/impc_obj.gif
new file mode 100644
index 0000000..ea94702
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/impc_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methdef_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methdef_obj.gif
new file mode 100644
index 0000000..f4a1ea1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methdef_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpri_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpri_obj.gif
new file mode 100644
index 0000000..2988716
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpri_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpro_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpro_obj.gif
new file mode 100644
index 0000000..563743d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpro_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpub_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpub_obj.gif
new file mode 100644
index 0000000..7d24707
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpub_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/packd_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/packd_obj.gif
new file mode 100644
index 0000000..2556b45
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/packd_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/wizard/newjprj_wiz.png b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/wizard/newjprj_wiz.png
new file mode 100644
index 0000000..dcc8c15
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/wizard/newjprj_wiz.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.jdt/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id1"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaAnnotationHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaAnnotationHandler.java
new file mode 100644
index 0000000..67b973a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaAnnotationHandler.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+
+public class NewJavaAnnotationHandler {
+	@Execute
+	public void createFile() {
+		
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaClassHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaClassHandler.java
new file mode 100644
index 0000000..81d77dd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaClassHandler.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+public class NewJavaClassHandler {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaEnumHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaEnumHandler.java
new file mode 100644
index 0000000..93cf96b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaEnumHandler.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+public class NewJavaEnumHandler {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaInterfaceHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaInterfaceHandler.java
new file mode 100644
index 0000000..1e0676c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaInterfaceHandler.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+public class NewJavaInterfaceHandler {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTImageServiceProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTImageServiceProvider.java
new file mode 100644
index 0000000..68b23a3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTImageServiceProvider.java
@@ -0,0 +1,39 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.e4.demo.simpleide.services.AbstractBundleImageProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class JDTImageServiceProvider extends AbstractBundleImageProvider {
+	private static final Bundle BUNDLE = FrameworkUtil.getBundle(JDTImageServiceProvider.class);
+	private static final String BUNDLE_NAME = BUNDLE.getSymbolicName();
+	
+	public static final String IMG_PACKAGE_DECL = BUNDLE_NAME + ".IMG_PACKAGE_DECL";
+	public static final String IMG_IMPORTCONTAINER_DECL = BUNDLE_NAME + ".IMG_IMPORTCONTAINER_DECL";
+	
+	private static final Map<String, String> IMAGEMAP = Collections.unmodifiableMap(new HashMap<String, String>() {
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = 1L;
+
+		{
+			put(JDTImageServiceProvider.IMG_PACKAGE_DECL, "/icons/outline/packd_obj.gif");
+			put(JDTImageServiceProvider.IMG_IMPORTCONTAINER_DECL, "/icons/impc_obj.gif");
+		}
+	});
+	
+	@Override
+	protected Map<String, String> getImageMap() {
+		return IMAGEMAP;
+	}
+
+	@Override
+	protected Bundle getBundle(String imageKey) {
+		return BUNDLE;
+	}
+	
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTProjectService.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTProjectService.java
new file mode 100644
index 0000000..8c7a5d5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTProjectService.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+public class JDTProjectService implements IProjectService {
+
+	public String getIconURI() {
+		return "platform:/plugin/" + FrameworkUtil.getBundle(getClass()).getSymbolicName() +"/icons/newjprj_wiz.gif";
+	}
+
+	public String getLabel() {
+		return "Java Project";
+	}
+
+	public void createProject(Shell shell, IWorkspace workspace, StatusReporter statusReporter, Logger looger,
+			IProgressMonitor monitor, String projectName) {
+		final IProject project = workspace.getRoot().getProject(projectName);
+		final IProjectDescription pd = workspace
+				.newProjectDescription(projectName);
+		try {
+			workspace.run(new IWorkspaceRunnable() { 
+
+				public void run(IProgressMonitor monitor) throws CoreException {
+					if (!project.exists()) {
+						project.create(pd, monitor);
+						JavaCore.create(project);
+					}
+					
+					if (!project.isOpen()) {
+						project.open(monitor);
+					}
+				}
+				
+			},monitor);
+		} catch (CoreException e) {
+			// TODO: handle exception
+		}
+		
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.java
new file mode 100644
index 0000000..5b41ebd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal;
+
+public interface JavaUIMessages {
+
+	String JavaElementLabels_onClassPathOf(String string, String lastSegment);
+
+	String JavaElementLabels_category(String string);
+
+	String JavaElementLabels_anonym_type(String supertypeName);
+
+	String JavaElementLabels_anonym();
+
+	String JavaElementLabels_initializer();
+
+	String JavaElementLabels_import_container();
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.properties b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.properties
new file mode 100644
index 0000000..3cca25b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.properties
@@ -0,0 +1,6 @@
+JavaElementLabels_onClassPathOf=\ (from {0} of {1})
+JavaElementLabels_category=[{0}]
+JavaElementLabels_anonym_type=new {0}() '{'...}
+JavaElementLabels_anonym=new Anonymous
+JavaElementLabels_initializer={...}
+JavaElementLabels_import_container=import declarations
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/IJDTSelection.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/IJDTSelection.java
new file mode 100644
index 0000000..963f71b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/IJDTSelection.java
@@ -0,0 +1,5 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor;
+
+public interface IJDTSelection {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JDTOutlinePage.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JDTOutlinePage.java
new file mode 100644
index 0000000..20b1de2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JDTOutlinePage.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor;
+
+import java.util.Vector;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer.AppearanceAwareLabelProvider;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer.JavaElementLabels;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class JDTOutlinePage {
+	// // FIXME We should use image service and pooling
+	// private static Image PACKAGE_DECL;
+	// private static Image IMPORT_CONTAINER_DECL;
+	// private static Image IMPORT_DECL;
+	//
+	// private static Image PUBLIC_CLASS_DECL;
+	// private static Image PACKAGE_CLASS_DECL;
+	//
+	// private static Image PUBLIC_METHOD_DECL;
+	// private static Image PACKAGE_METHOD_DECL;
+	// private static Image PROTECTED_METHOD_DECL;
+	// private static Image PRIVATE_METHOD_DECL;
+
+	private class ContentProvider implements ITreeContentProvider {
+		private final Object[] EMPTY = new Object[0];
+
+		public void dispose() {
+
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+
+		}
+
+		public Object[] getElements(Object inputElement) {
+			return getChildren(inputElement);
+		}
+
+		protected boolean matches(IJavaElement element) {
+			if (element.getElementType() == IJavaElement.METHOD) {
+				String name = element.getElementName();
+				return (name != null && name.indexOf('<') >= 0);
+			}
+			return false;
+		}
+
+		protected IJavaElement[] filter(IJavaElement[] children) {
+			boolean initializers = false;
+			for (int i = 0; i < children.length; i++) {
+				if (matches(children[i])) {
+					initializers = true;
+					break;
+				}
+			}
+
+			if (!initializers)
+				return children;
+
+			Vector<IJavaElement> v = new Vector<IJavaElement>();
+			for (int i = 0; i < children.length; i++) {
+				if (matches(children[i]))
+					continue;
+				v.addElement(children[i]);
+			}
+
+			IJavaElement[] result = new IJavaElement[v.size()];
+			v.copyInto(result);
+			return result;
+		}
+
+		public Object[] getChildren(Object parentElement) {
+			if (parentElement instanceof IParent) {
+				IParent c = (IParent) parentElement;
+				try {
+					return filter(c.getChildren());
+				} catch (JavaModelException x) {
+
+				}
+			}
+			return EMPTY;
+		}
+
+		public Object getParent(Object element) {
+			if (element instanceof IJavaElement) {
+				IJavaElement e = (IJavaElement) element;
+				return e.getParent();
+			}
+			return null;
+		}
+
+		public boolean hasChildren(Object element) {
+			return getChildren(element).length > 0;
+		}
+	}
+
+	// private class LabelProviderImpl extends DelegatingStyledCellLabelProvider
+	// {
+	// public LabelProviderImpl() {
+	// super();
+	// // TODO Auto-generated constructor stub
+	// }
+	//
+	// @Override
+	// public void update(ViewerCell cell) {
+	// IJavaElement obj = (IJavaElement) cell.getElement();
+	// if (obj instanceof IAnnotation) {
+	// } else if (obj instanceof IImportContainer) {
+	// cell.setImage(IMPORT_CONTAINER_DECL);
+	// cell.setText("import declarations");
+	// } else if (obj instanceof IImportDeclaration) {
+	// cell.setImage(IMPORT_DECL);
+	// cell.setText(obj.getElementName());
+	// } else if (obj instanceof IPackageDeclaration) {
+	// cell.setImage(PACKAGE_DECL);
+	// cell.setText(obj.getElementName());
+	// } else if (obj instanceof IType) {
+	// IType type = (IType) obj;
+	// try {
+	// if (type.isLocal()) {
+	// cell.setText(type.toString());
+	// System.err.println(type);
+	// } else {
+	// int flags = type.getFlags();
+	// if (Flags.isInterface(flags)) {
+	//
+	// } else {
+	// if (Flags.isPublic(flags)) {
+	// cell.setImage(PUBLIC_CLASS_DECL);
+	// } else if (Flags.isPrivate(flags)) {
+	//
+	// } else if (Flags.isPackageDefault(flags)) {
+	// cell.setImage(PACKAGE_CLASS_DECL);
+	// }
+	// }
+	//
+	// cell.setText(obj.getElementName());
+	// }
+	// } catch (JavaModelException e) {
+	// // TODO Auto-generated catch block
+	// e.printStackTrace();
+	// }
+	// } else if (obj instanceof IMethod) {
+	// IMethod type = (IMethod) obj;
+	// try {
+	// int flags = type.getFlags();
+	//
+	// if (Flags.isPrivate(flags)) {
+	// cell.setImage(PRIVATE_METHOD_DECL);
+	// } else if (Flags.isPackageDefault(flags)) {
+	// cell.setImage(PACKAGE_CLASS_DECL);
+	// } else if (Flags.isProtected(flags)) {
+	// cell.setImage(PROTECTED_METHOD_DECL);
+	// } else {
+	// cell.setImage(PUBLIC_METHOD_DECL);
+	// }
+	// } catch (JavaModelException e) {
+	// // TODO Auto-generated catch block
+	// e.printStackTrace();
+	// }
+	// cell.setText(obj.getElementName());
+	// } else if (obj instanceof IField) {
+	// cell.setText(obj.getElementName());
+	// } else {
+	// cell.setText(obj.getClass().getName());
+	// }
+	//
+	// System.err.println(obj.getClass());
+	//
+	// super.update(cell);
+	// }
+	// }
+
+	@Inject
+	public JDTOutlinePage(Composite parent,
+			@Named(IServiceConstants.ACTIVE_PART) MPart part,
+			IWorkspace workspace, Logger logger,
+			INLSLookupFactoryService nlsFactory) {
+		// if (PACKAGE_DECL == null) {
+		// initImages(parent);
+		// }
+		parent.setLayout(new FillLayout());
+
+		JavaEditor editor = (JavaEditor) part.getObject();
+
+		// FIXME We need to cache this!
+		JavaUIMessages messages = nlsFactory
+				.createNLSLookup(JavaUIMessages.class);
+
+		final AppearanceAwareLabelProvider lprovider = new AppearanceAwareLabelProvider(
+				AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS
+						| JavaElementLabels.F_APP_TYPE_SIGNATURE
+						| JavaElementLabels.ALL_CATEGORY, AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS, logger, messages);
+
+		TreeViewer viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
+		viewer.setContentProvider(new ContentProvider());
+		viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(lprovider));
+		viewer.setInput(editor.getCompilationUnit());
+		viewer.expandAll();
+	}
+
+	// private void initImages(Composite parent) {
+	// PACKAGE_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/packd_obj.gif"));
+	// IMPORT_CONTAINER_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/impc_obj.gif"));
+	// IMPORT_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/imp_obj.gif"));
+	// PUBLIC_CLASS_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/class_obj.gif"));
+	// PACKAGE_CLASS_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/class_default_obj.gif"));
+	// PUBLIC_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/methpub_obj.gif"));
+	// PACKAGE_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/methdef_obj.gif"));
+	// PROTECTED_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/methpro_obj.gif"));
+	// PRIVATE_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+	// .getClassLoader().getResourceAsStream(
+	// "/icons/outline/methpri_obj.gif"));
+	// }
+
+	@Inject
+	public void setSelection(
+			@Optional @Named(IServiceConstants.ACTIVE_SELECTION) IJDTSelection selection) {
+		if (selection != null) {
+			System.err.println("Updating to JavaSelection '" + selection + "'");
+		}
+	}
+
+	@PreDestroy
+	public void dispose() {
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JavaEditor.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JavaEditor.java
new file mode 100644
index 0000000..f0910ac
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JavaEditor.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor;
+
+import javax.inject.Inject;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.IJavaColorConstants;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.IJavaPartitions;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.JavaSourceViewerConfiguration;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.JavaTextTools;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.PreferenceConstants;
+import org.eclipse.e4.demo.simpleide.outline.IOutlinePageProvider;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.VerticalRuler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaEditor implements IOutlinePageProvider {
+	private static final int VERTICAL_RULER_WIDTH = 12;
+
+	private IDocumentInput input;
+	
+	private static PreferenceStore store = new PreferenceStore();
+	
+	static {
+		store.setDefault(IJavaColorConstants.JAVA_MULTI_LINE_COMMENT, "102,153,102"); // 669966
+
+		store.setDefault(IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT, "102,153,102"); // 669966
+		
+		store.setDefault(IJavaColorConstants.JAVA_STRING, "51,0,255"); // 3300FF
+		
+		store.setDefault(IJavaColorConstants.JAVADOC_DEFAULT, "51,102,204"); // 3366CC
+		
+		store.setDefault(IJavaColorConstants.JAVADOC_KEYWORD, "51,102,204");
+		store.setDefault(IJavaColorConstants.JAVADOC_KEYWORD+PreferenceConstants.EDITOR_BOLD_SUFFIX, true);
+		
+		store.setDefault(IJavaColorConstants.JAVADOC_LINK, "255,0,255");
+		
+		store.setDefault(IJavaColorConstants.JAVADOC_TAG, "255,255,0");
+		
+		store.setDefault(IJavaColorConstants.TASK_TAG, "255,100,0");
+		
+		store.setDefault(IJavaColorConstants.JAVA_KEYWORD, "153,51,102"); // 993366
+		store.setDefault(IJavaColorConstants.JAVA_KEYWORD+PreferenceConstants.EDITOR_BOLD_SUFFIX, true);
+		
+		store.setDefault(IJavaColorConstants.JAVA_DEFAULT, "0,0,0");
+		
+		store.setDefault(IJavaColorConstants.JAVA_KEYWORD_RETURN, "153,51,102"); // 993366
+		store.setDefault(IJavaColorConstants.JAVA_KEYWORD_RETURN+PreferenceConstants.EDITOR_BOLD_SUFFIX, true);
+		
+		store.setDefault(IJavaColorConstants.JAVA_OPERATOR, "0,0,0");
+		store.setDefault(IJavaColorConstants.JAVA_BRACKET, "0,0,0");
+	}
+	
+	private static final JavaTextTools textTools = new JavaTextTools(store, true);
+
+	private ICompilationUnit compilationUnit;
+	
+	//TODO We should try to get access to the file through injection
+	private MPart part;
+	private IWorkspace workspace;
+	
+	@Inject
+	public JavaEditor(Composite parent, IDocumentInput input, IWorkspace workspace, MPart part) {
+		this.input = input;
+		this.part = part;
+		this.workspace = workspace;
+		VerticalRuler verticalRuler = new VerticalRuler(VERTICAL_RULER_WIDTH);
+		
+		int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
+		SourceViewer viewer = new SourceViewer(parent, verticalRuler, styles);
+		
+		Font f = null;
+		if( ! JFaceResources.getFontRegistry().hasValueFor("JavaEditorFont") ) {
+			if( SWT.getPlatform().equals("carbon") || SWT.getPlatform().equals("cocoa") ) {
+				JFaceResources.getFontRegistry().put("JavaEditorFont", new FontData[] {new FontData("Monaco",11,SWT.NONE)});
+			}
+		}
+		
+		f = JFaceResources.getFontRegistry().get("JavaEditorFont");
+		viewer.getTextWidget().setFont(f);
+		
+		viewer.configure(new JavaSourceViewerConfiguration(textTools));
+		IDocument document = input.getDocument();
+		
+		textTools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
+		viewer.setDocument(document);
+	}
+	
+	ICompilationUnit getCompilationUnit() {
+		if( compilationUnit == null ) {
+			String uri = ((MInputPart)part).getInputURI();
+			Path p = new Path(uri);
+			IFile file = workspace.getRoot().getFile(p);
+			
+			compilationUnit = (ICompilationUnit) JavaCore.create(file);
+		}
+		
+		return compilationUnit;
+	}
+	
+	@Persist
+	public void save() {
+		System.err.println("Saving ...");
+		input.save();
+	}
+	
+	public Class<?> getOutlineClass() {
+		return JDTOutlinePage.class;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/AbstractJavaScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/AbstractJavaScanner.java
new file mode 100644
index 0000000..99c0a24
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/AbstractJavaScanner.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+
+/**
+ * Initialized with a color manager and a preference store, its subclasses are
+ * only responsible for providing a list of preference keys for based on which tokens
+ * are generated and to use this tokens to define the rules controlling this scanner.
+ * <p>
+ * This scanner stores the color defined by the color preference key into
+ * the color manager under the same key.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_BOLD_SUFFIX} are used
+ * to retrieve whether the token is rendered in bold.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_ITALIC_SUFFIX} are used
+ * to retrieve whether the token is rendered in italic.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_STRIKETHROUGH_SUFFIX} are used
+ * to retrieve whether the token is rendered in strikethrough.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_UNDERLINE_SUFFIX} are used
+ * to retrieve whether the token is rendered in underline.
+ * </p>
+ */
+public abstract class AbstractJavaScanner extends BufferedRuleBasedScanner {
+
+
+	private IColorManager fColorManager;
+	private IPreferenceStore fPreferenceStore;
+
+	private Map<String,Token> fTokenMap= new HashMap<String,Token>();
+	private String[] fPropertyNamesColor;
+	/**
+	 * Preference keys for boolean preferences which are <code>true</code>,
+	 * iff the corresponding token should be rendered bold.
+	 */
+	private String[] fPropertyNamesBold;
+	/**
+	 * Preference keys for boolean preferences which are <code>true</code>,
+	 * iff the corresponding token should be rendered italic.
+	 *
+	 * @since 3.0
+	 */
+	private String[] fPropertyNamesItalic;
+	/**
+	 * Preference keys for boolean preferences which are <code>true</code>,
+	 * iff the corresponding token should be rendered strikethrough.
+	 *
+	 * @since 3.1
+	 */
+	private String[] fPropertyNamesStrikethrough;
+	/**
+	 * Preference keys for boolean preferences which are <code>true</code>,
+	 * iff the corresponding token should be rendered underline.
+	 *
+	 * @since 3.1
+	 */
+	private String[] fPropertyNamesUnderline;
+
+
+	private boolean fNeedsLazyColorLoading;
+
+	/**
+	 * Returns an array of preference keys which define the tokens
+	 * used in the rules of this scanner.
+	 * <p>
+	 * The preference key is used access the color in the preference
+	 * store and in the color manager.
+	 * </p>
+	 * <p>
+	 * Preference key + {@link PreferenceConstants#EDITOR_BOLD_SUFFIX} is used
+	 * to retrieve whether the token is rendered in bold.
+	 * </p>
+	 * <p>
+	 * Preference key + {@link PreferenceConstants#EDITOR_ITALIC_SUFFIX} is used
+	 * to retrieve whether the token is rendered in italic.
+	 * </p>
+	 * <p>
+	 * Preference key + {@link PreferenceConstants#EDITOR_UNDERLINE_SUFFIX} is used
+	 * to retrieve whether the token is rendered underlined.
+	 * </p>
+	 * <p>
+	 * Preference key + {@link PreferenceConstants#EDITOR_STRIKETHROUGH_SUFFIX} is used
+	 * to retrieve whether the token is rendered stricken out.
+	 * </p>
+	 */
+	abstract protected String[] getTokenProperties();
+
+	/**
+	 * Creates the list of rules controlling this scanner.
+	 */
+	abstract protected List<IRule> createRules();
+
+
+	/**
+	 * Creates an abstract Java scanner.
+	 */
+	public AbstractJavaScanner(IColorManager manager, IPreferenceStore store) {
+		super();
+		fColorManager= manager;
+		fPreferenceStore= store;
+	}
+
+	/**
+	 * Must be called after the constructor has been called.
+	 */
+	public final void initialize() {
+
+		fPropertyNamesColor= getTokenProperties();
+		int length= fPropertyNamesColor.length;
+		fPropertyNamesBold= new String[length];
+		fPropertyNamesItalic= new String[length];
+		fPropertyNamesStrikethrough= new String[length];
+		fPropertyNamesUnderline= new String[length];
+
+		for (int i= 0; i < length; i++) {
+			fPropertyNamesBold[i]= getBoldKey(fPropertyNamesColor[i]);
+			fPropertyNamesItalic[i]= getItalicKey(fPropertyNamesColor[i]);
+			fPropertyNamesStrikethrough[i]= getStrikethroughKey(fPropertyNamesColor[i]);
+			fPropertyNamesUnderline[i]= getUnderlineKey(fPropertyNamesColor[i]);
+		}
+
+		fNeedsLazyColorLoading= Display.getCurrent() == null;
+		for (int i= 0; i < length; i++) {
+			if (fNeedsLazyColorLoading)
+				addTokenWithProxyAttribute(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
+			else
+				addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
+		}
+
+		initializeRules();
+	}
+
+	protected String getBoldKey(String colorKey) {
+		return colorKey + PreferenceConstants.EDITOR_BOLD_SUFFIX;
+	}
+
+	protected String getItalicKey(String colorKey) {
+		return colorKey + PreferenceConstants.EDITOR_ITALIC_SUFFIX;
+	}
+
+	protected String getStrikethroughKey(String colorKey) {
+		return colorKey + PreferenceConstants.EDITOR_STRIKETHROUGH_SUFFIX;
+	}
+
+	protected String getUnderlineKey(String colorKey) {
+		return colorKey + PreferenceConstants.EDITOR_UNDERLINE_SUFFIX;
+	}
+
+	public IToken nextToken() {
+		if (fNeedsLazyColorLoading)
+			resolveProxyAttributes();
+		return super.nextToken();
+	}
+
+	private void resolveProxyAttributes() {
+		if (fNeedsLazyColorLoading && Display.getCurrent() != null) {
+			for (int i= 0; i < fPropertyNamesColor.length; i++) {
+				addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
+			}
+			fNeedsLazyColorLoading= false;
+		}
+	}
+
+	private void addTokenWithProxyAttribute(String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
+		fTokenMap.put(colorKey, new Token(createTextAttribute(null, boldKey, italicKey, strikethroughKey, underlineKey)));
+	}
+
+	private void addToken(String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
+		if (fColorManager != null && colorKey != null && fColorManager.getColor(colorKey) == null) {
+			RGB rgb= PreferenceConverter.getColor(fPreferenceStore, colorKey);
+			if (fColorManager instanceof IColorManagerExtension) {
+				IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
+				ext.unbindColor(colorKey);
+				ext.bindColor(colorKey, rgb);
+			}
+		}
+
+		if (!fNeedsLazyColorLoading)
+			fTokenMap.put(colorKey, new Token(createTextAttribute(colorKey, boldKey, italicKey, strikethroughKey, underlineKey)));
+		else {
+			Token token= ((Token)fTokenMap.get(colorKey));
+			if (token != null)
+				token.setData(createTextAttribute(colorKey, boldKey, italicKey, strikethroughKey, underlineKey));
+		}
+	}
+
+	/**
+	 * Create a text attribute based on the given color, bold, italic, strikethrough and underline preference keys.
+	 *
+	 * @param colorKey the color preference key
+	 * @param boldKey the bold preference key
+	 * @param italicKey the italic preference key
+	 * @param strikethroughKey the strikethrough preference key
+	 * @param underlineKey the italic preference key
+	 * @return the created text attribute
+	 * @since 3.0
+	 */
+	private TextAttribute createTextAttribute(String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
+		Color color= null;
+		if (colorKey != null)
+			color= fColorManager.getColor(colorKey);
+
+		int style= fPreferenceStore.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL;
+		if (fPreferenceStore.getBoolean(italicKey))
+			style |= SWT.ITALIC;
+
+		if (fPreferenceStore.getBoolean(strikethroughKey))
+			style |= TextAttribute.STRIKETHROUGH;
+
+		if (fPreferenceStore.getBoolean(underlineKey))
+			style |= TextAttribute.UNDERLINE;
+
+		return new TextAttribute(color, null, style);
+	}
+
+	protected Token getToken(String key) {
+		if (fNeedsLazyColorLoading)
+			resolveProxyAttributes();
+		return (Token) fTokenMap.get(key);
+	}
+
+	private void initializeRules() {
+		List<IRule> rules= createRules();
+		if (rules != null) {
+			IRule[] result= new IRule[rules.size()];
+			rules.toArray(result);
+			setRules(result);
+		}
+	}
+
+	private int indexOf(String property) {
+		if (property != null) {
+			int length= fPropertyNamesColor.length;
+			for (int i= 0; i < length; i++) {
+				if (property.equals(fPropertyNamesColor[i]) || property.equals(fPropertyNamesBold[i]) || property.equals(fPropertyNamesItalic[i]) || property.equals(fPropertyNamesStrikethrough[i]) || property.equals(fPropertyNamesUnderline[i]))
+					return i;
+			}
+		}
+		return -1;
+	}
+
+	public boolean affectsBehavior(PropertyChangeEvent event) {
+		return indexOf(event.getProperty()) >= 0;
+	}
+
+	public void adaptToPreferenceChange(PropertyChangeEvent event) {
+		String p= event.getProperty();
+		int index= indexOf(p);
+		Token token= getToken(fPropertyNamesColor[index]);
+		if (fPropertyNamesColor[index].equals(p))
+			adaptToColorChange(token, event);
+		else if (fPropertyNamesBold[index].equals(p))
+			adaptToStyleChange(token, event, SWT.BOLD);
+		else if (fPropertyNamesItalic[index].equals(p))
+			adaptToStyleChange(token, event, SWT.ITALIC);
+		else if (fPropertyNamesStrikethrough[index].equals(p))
+			adaptToStyleChange(token, event, TextAttribute.STRIKETHROUGH);
+		else if (fPropertyNamesUnderline[index].equals(p))
+			adaptToStyleChange(token, event, TextAttribute.UNDERLINE);
+	}
+
+	private void adaptToColorChange(Token token, PropertyChangeEvent event) {
+		RGB rgb= null;
+
+		Object value= event.getNewValue();
+		if (value instanceof RGB)
+			rgb= (RGB) value;
+		else if (value instanceof String)
+			rgb= StringConverter.asRGB((String) value);
+
+		if (rgb != null) {
+
+			String property= event.getProperty();
+			Color color= fColorManager.getColor(property);
+
+			if ((color == null || !rgb.equals(color.getRGB())) && fColorManager instanceof IColorManagerExtension) {
+				IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
+
+			 	ext.unbindColor(property);
+			 	ext.bindColor(property, rgb);
+
+				color= fColorManager.getColor(property);
+			}
+
+			Object data= token.getData();
+			if (data instanceof TextAttribute) {
+				TextAttribute oldAttr= (TextAttribute) data;
+				token.setData(new TextAttribute(color, oldAttr.getBackground(), oldAttr.getStyle()));
+			}
+		}
+	}
+
+	private void adaptToStyleChange(Token token, PropertyChangeEvent event, int styleAttribute) {
+		boolean eventValue= false;
+		Object value= event.getNewValue();
+		if (value instanceof Boolean)
+			eventValue= ((Boolean) value).booleanValue();
+		else if (IPreferenceStore.TRUE.equals(value))
+			eventValue= true;
+
+		Object data= token.getData();
+		if (data instanceof TextAttribute) {
+			TextAttribute oldAttr= (TextAttribute) data;
+			boolean activeValue= (oldAttr.getStyle() & styleAttribute) == styleAttribute;
+			if (activeValue != eventValue)
+				token.setData(new TextAttribute(oldAttr.getForeground(), oldAttr.getBackground(), eventValue ? oldAttr.getStyle() | styleAttribute : oldAttr.getStyle() & ~styleAttribute));
+		}
+	}
+	/**
+	 * Returns the preference store.
+	 *
+	 * @return the preference store.
+	 *
+	 * @since 3.0
+	 */
+	protected IPreferenceStore getPreferenceStore() {
+		return fPreferenceStore;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/BufferedDocumentScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/BufferedDocumentScanner.java
new file mode 100644
index 0000000..920bccd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/BufferedDocumentScanner.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+
+
+/**
+ * A buffered document scanner. The buffer always contains a section
+ * of a fixed size of the document to be scanned.
+ */
+
+public final class BufferedDocumentScanner implements ICharacterScanner {
+
+	/** The document being scanned. */
+	private IDocument fDocument;
+	/** The offset of the document range to scan. */
+	private int fRangeOffset;
+	/** The length of the document range to scan. */
+	private int fRangeLength;
+	/** The delimiters of the document. */
+	private char[][] fDelimiters;
+
+	/** The buffer. */
+	private final char[] fBuffer;
+	/** The offset of the buffer within the document. */
+	private int fBufferOffset;
+	/** The valid length of the buffer for access. */
+	private int fBufferLength;
+	/** The offset of the scanner within the buffer. */
+	private int fOffset;
+
+
+	/**
+	 * Creates a new buffered document scanner.
+	 * The buffer size is set to the given number of characters.
+	 *
+	 * @param size the buffer size
+	 */
+	public BufferedDocumentScanner(int size) {
+		Assert.isTrue(size >= 1);
+		fBuffer= new char[size];
+	}
+
+	/**
+	 * Fills the buffer with the contents of the document starting at the given offset.
+	 *
+	 * @param offset the document offset at which the buffer starts
+	 */
+	private final void updateBuffer(int offset) {
+
+		fBufferOffset= offset;
+
+		if (fBufferOffset + fBuffer.length > fRangeOffset + fRangeLength)
+			fBufferLength= fRangeLength - (fBufferOffset - fRangeOffset);
+		else
+			fBufferLength= fBuffer.length;
+
+		try {
+			final String content= fDocument.get(fBufferOffset, fBufferLength);
+			content.getChars(0, fBufferLength, fBuffer, 0);
+		} catch (BadLocationException e) {
+		}
+	}
+
+	/**
+	 * Configures the scanner by providing access to the document range over which to scan.
+	 *
+	 * @param document the document to scan
+	 * @param offset the offset of the document range to scan
+	 * @param length the length of the document range to scan
+	 */
+	public final void setRange(IDocument document, int offset, int length) {
+
+		fDocument= document;
+		fRangeOffset= offset;
+		fRangeLength= length;
+
+		String[] delimiters= document.getLegalLineDelimiters();
+		fDelimiters= new char[delimiters.length][];
+		for (int i= 0; i < delimiters.length; i++)
+			fDelimiters[i]= delimiters[i].toCharArray();
+
+		updateBuffer(offset);
+		fOffset= 0;
+	}
+
+	/*
+	 * @see ICharacterScanner#read()
+	 */
+	public final int read() {
+
+		if (fOffset == fBufferLength) {
+			int end= fBufferOffset + fBufferLength;
+			if (end == fDocument.getLength() || end == fRangeOffset + fRangeLength)
+				return EOF;
+			else {
+				updateBuffer(fBufferOffset + fBufferLength);
+				fOffset= 0;
+			}
+		}
+
+		try {
+			return fBuffer[fOffset++];
+		} catch (ArrayIndexOutOfBoundsException ex) {
+			StringBuffer buf= new StringBuffer();
+			buf.append("Detailed state of 'BufferedDocumentScanner:'"); //$NON-NLS-1$
+			buf.append("\n\tfOffset= "); //$NON-NLS-1$
+			buf.append(fOffset);
+			buf.append("\n\tfBufferOffset= "); //$NON-NLS-1$
+			buf.append(fBufferOffset);
+			buf.append("\n\tfBufferLength= "); //$NON-NLS-1$
+			buf.append(fBufferLength);
+			buf.append("\n\tfRangeOffset= "); //$NON-NLS-1$
+			buf.append(fRangeOffset);
+			buf.append("\n\tfRangeLength= "); //$NON-NLS-1$
+			buf.append(fRangeLength);
+			System.err.println(buf.toString()); //FIXME Logging
+//			JavaPlugin.logErrorMessage(buf.toString());
+			throw ex;
+		}
+	}
+
+	/*
+	 * @see ICharacterScanner#unread
+	 */
+	public final void unread() {
+
+		if (fOffset == 0) {
+			if (fBufferOffset == fRangeOffset) {
+				// error: BOF
+			} else {
+				updateBuffer(fBufferOffset - fBuffer.length);
+				fOffset= fBuffer.length - 1;
+			}
+		} else {
+			--fOffset;
+		}
+	}
+
+	/*
+	 * @see ICharacterScanner#getColumn()
+	 */
+	public final int getColumn() {
+
+		try {
+			final int offset= fBufferOffset + fOffset;
+			final int line= fDocument.getLineOfOffset(offset);
+			final int start= fDocument.getLineOffset(line);
+			return offset - start;
+		} catch (BadLocationException e) {
+		}
+
+		return -1;
+	}
+
+	/*
+	 * @see ICharacterScanner#getLegalLineDelimiters()
+	 */
+	public final char[][] getLegalLineDelimiters() {
+		return fDelimiters;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/CombinedWordRule.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/CombinedWordRule.java
new file mode 100644
index 0000000..c497498
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/CombinedWordRule.java
@@ -0,0 +1,370 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+
+
+/**
+ * An implementation of <code>IRule</code> capable of detecting words.
+ * <p>
+ * Word rules also allow for the association of tokens with specific words.
+ * That is, not only can the rule be used to provide tokens for exact matches,
+ * but also for the generalized notion of a word in the context in which it is used.
+ * A word rules uses a word detector to determine what a word is.</p>
+ * <p>
+ * This word rule allows a word detector to be shared among different word matchers.
+ * Its up to the word matchers to decide if a word matches and, in this a case, which
+ * token is associated with that word.
+ * </p>
+ *
+ * @see IWordDetector
+ * @since 3.0
+ */
+public class CombinedWordRule implements IRule {
+
+	/**
+	 * Word matcher, that associates matched words with tokens.
+	 */
+	public static class WordMatcher {
+
+		/** The table of predefined words and token for this matcher */
+		private Map<CharacterBuffer,IToken> fWords= new HashMap<CharacterBuffer,IToken>();
+
+		/**
+		 * Adds a word and the token to be returned if it is detected.
+		 *
+		 * @param word the word this rule will search for, may not be <code>null</code>
+		 * @param token the token to be returned if the word has been found, may not be <code>null</code>
+		 */
+		public void addWord(String word, IToken token) {
+			Assert.isNotNull(word);
+			Assert.isNotNull(token);
+
+			fWords.put(new CharacterBuffer(word), token);
+		}
+
+		/**
+		 * Returns the token associated to the given word and the scanner state.
+		 *
+		 * @param scanner the scanner
+		 * @param word the word
+		 * @return the token or <code>null</code> if none is associated by this matcher
+		 */
+		public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) {
+			IToken token= (IToken) fWords.get(word);
+			if (token != null)
+				return token;
+			return Token.UNDEFINED;
+		}
+
+		/**
+		 * Removes all words.
+		 */
+		public void clearWords() {
+			fWords.clear();
+		}
+	}
+
+	/**
+	 * Character buffer, mutable <b>or</b> suitable for use as key in hash maps.
+	 */
+	public static class CharacterBuffer {
+
+		/** Buffer content */
+		private char[] fContent;
+		/** Buffer content size */
+		private int fLength= 0;
+
+		/** Is hash code cached? */
+		private boolean fIsHashCached= false;
+		/** The hash code */
+		private int fHashCode;
+
+		/**
+		 * Initialize with the given capacity.
+		 *
+		 * @param capacity the initial capacity
+		 */
+		public CharacterBuffer(int capacity) {
+			fContent= new char[capacity];
+		}
+
+		/**
+		 * Initialize with the given content.
+		 *
+		 * @param content the initial content
+		 */
+		public CharacterBuffer(String content) {
+			fContent= content.toCharArray();
+			fLength= content.length();
+		}
+
+		/**
+		 * Empties this buffer.
+		 */
+		public void clear() {
+			fIsHashCached= false;
+			fLength= 0;
+		}
+
+		/**
+		 * Appends the given character to the buffer.
+		 *
+		 * @param c the character
+		 */
+		public void append(char c) {
+			fIsHashCached= false;
+			if (fLength == fContent.length) {
+				char[] old= fContent;
+				fContent= new char[old.length << 1];
+				System.arraycopy(old, 0, fContent, 0, old.length);
+			}
+			fContent[fLength++]= c;
+		}
+
+		/**
+		 * Returns the length of the content.
+		 *
+		 * @return the length
+		 */
+		public int length() {
+			return fLength;
+		}
+
+		/**
+		 * Returns the content as string.
+		 *
+		 * @return the content
+		 */
+		public String toString() {
+			return new String(fContent, 0, fLength);
+		}
+
+		/**
+		 * Returns the character at the given position.
+		 *
+		 * @param i the position
+		 * @return the character at position <code>i</code>
+		 */
+		public char charAt(int i) {
+			return fContent[i];
+		}
+
+		/*
+		 * @see java.lang.Object#hashCode()
+		 */
+		public int hashCode() {
+			if (fIsHashCached)
+				return fHashCode;
+
+			int hash= 0;
+			for (int i= 0, n= fLength; i < n; i++)
+				hash= 29*hash + fContent[i];
+			fHashCode= hash;
+			fIsHashCached= true;
+			return hash;
+		}
+
+
+		/*
+		 * @see java.lang.Object#equals(java.lang.Object)
+		 */
+		public boolean equals(Object obj) {
+			if (obj == this)
+				return true;
+			if (!(obj instanceof CharacterBuffer))
+				return false;
+			CharacterBuffer buffer= (CharacterBuffer) obj;
+			int length= buffer.length();
+			if (length != fLength)
+				return false;
+			for (int i= 0; i < length; i++)
+				if (buffer.charAt(i) != fContent[i])
+					return false;
+			return true;
+		}
+
+		/**
+		 * Is the content equal to the given string?
+		 *
+		 * @param string the string
+		 * @return <code>true</code> iff the content is the same character sequence as in the string
+		 */
+		public boolean equals(String string) {
+			int length= string.length();
+			if (length != fLength)
+				return false;
+			for (int i= 0; i < length; i++)
+				if (string.charAt(i) != fContent[i])
+					return false;
+			return true;
+		}
+	}
+
+	/** Internal setting for the uninitialized column constraint */
+	private static final int UNDEFINED= -1;
+
+	/** The word detector used by this rule */
+	private IWordDetector fDetector;
+	/** The default token to be returned on success and if nothing else has been specified. */
+	private IToken fDefaultToken;
+	/** The column constraint */
+	private int fColumn= UNDEFINED;
+	/** Buffer used for pattern detection */
+	private CharacterBuffer fBuffer= new CharacterBuffer(16);
+
+	/** List of word matchers */
+	private List<WordMatcher> fMatchers= new ArrayList<WordMatcher>();
+
+	/**
+	 * Creates a rule which, with the help of an word detector, will return the token
+	 * associated with the detected word. If no token has been associated, the scanner
+	 * will be rolled back and an undefined token will be returned in order to allow
+	 * any subsequent rules to analyze the characters.
+	 *
+	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
+	 *
+	 * @see WordMatcher#addWord(String, IToken)
+	 */
+	public CombinedWordRule(IWordDetector detector) {
+		this(detector, null, Token.UNDEFINED);
+	}
+
+	/**
+	 * Creates a rule which, with the help of an word detector, will return the token
+	 * associated with the detected word. If no token has been associated, the
+	 * specified default token will be returned.
+	 *
+	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
+	 * @param defaultToken the default token to be returned on success
+	 *		if nothing else is specified, may not be <code>null</code>
+	 *
+	 * @see WordMatcher#addWord(String, IToken)
+	 */
+	public CombinedWordRule(IWordDetector detector, IToken defaultToken) {
+		this(detector, null, defaultToken);
+	}
+
+	/**
+	 * Creates a rule which, with the help of an word detector, will return the token
+	 * associated with the detected word. If no token has been associated, the scanner
+	 * will be rolled back and an undefined token will be returned in order to allow
+	 * any subsequent rules to analyze the characters.
+	 *
+	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
+	 * @param matcher the initial word matcher
+	 *
+	 * @see WordMatcher#addWord(String, IToken)
+	 */
+	public CombinedWordRule(IWordDetector detector, WordMatcher matcher) {
+		this(detector, matcher, Token.UNDEFINED);
+	}
+
+	/**
+	 * Creates a rule which, with the help of an word detector, will return the token
+	 * associated with the detected word. If no token has been associated, the
+	 * specified default token will be returned.
+	 *
+	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
+	 * @param matcher the initial word matcher
+	 * @param defaultToken the default token to be returned on success
+	 *		if nothing else is specified, may not be <code>null</code>
+	 *
+	 * @see WordMatcher#addWord(String, IToken)
+	 */
+	public CombinedWordRule(IWordDetector detector, WordMatcher matcher, IToken defaultToken) {
+
+		Assert.isNotNull(detector);
+		Assert.isNotNull(defaultToken);
+
+		fDetector= detector;
+		fDefaultToken= defaultToken;
+		if (matcher != null)
+			addWordMatcher(matcher);
+	}
+
+
+	/**
+	 * Adds the given matcher.
+	 *
+	 * @param matcher the matcher
+	 */
+	public void addWordMatcher(WordMatcher matcher) {
+		fMatchers.add(matcher);
+	}
+
+	/**
+	 * Sets a column constraint for this rule. If set, the rule's token
+	 * will only be returned if the pattern is detected starting at the
+	 * specified column. If the column is smaller then 0, the column
+	 * constraint is considered removed.
+	 *
+	 * @param column the column in which the pattern starts
+	 */
+	public void setColumnConstraint(int column) {
+		if (column < 0)
+			column= UNDEFINED;
+		fColumn= column;
+	}
+
+	/*
+	 * @see IRule#evaluate(ICharacterScanner)
+	 */
+	public IToken evaluate(ICharacterScanner scanner) {
+		int c= scanner.read();
+		if (fDetector.isWordStart((char) c)) {
+			if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+
+				fBuffer.clear();
+				do {
+					fBuffer.append((char) c);
+					c= scanner.read();
+				} while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
+				scanner.unread();
+
+				for (int i= 0, n= fMatchers.size(); i < n; i++) {
+					IToken token= ((WordMatcher) fMatchers.get(i)).evaluate(scanner, fBuffer);
+					if (!token.isUndefined())
+						return token;
+				}
+
+				if (fDefaultToken.isUndefined())
+					unreadBuffer(scanner);
+
+				return fDefaultToken;
+			}
+		}
+
+		scanner.unread();
+		return Token.UNDEFINED;
+	}
+
+	/**
+	 * Returns the characters in the buffer to the scanner.
+	 *
+	 * @param scanner the scanner to be used
+	 */
+	private void unreadBuffer(ICharacterScanner scanner) {
+		for (int i= fBuffer.length() - 1; i >= 0; i--)
+			scanner.unread();
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/FastJavaPartitionScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/FastJavaPartitionScanner.java
new file mode 100644
index 0000000..e0617a1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/FastJavaPartitionScanner.java
@@ -0,0 +1,533 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+
+/**
+ * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments,
+ * Java strings and Java characters.
+ */
+public class FastJavaPartitionScanner implements IPartitionTokenScanner, IJavaPartitions {
+
+	// states
+	private static final int JAVA= 0;
+	private static final int SINGLE_LINE_COMMENT= 1;
+	private static final int MULTI_LINE_COMMENT= 2;
+	private static final int JAVADOC= 3;
+	private static final int CHARACTER= 4;
+	private static final int STRING= 5;
+
+	// beginning of prefixes and postfixes
+	private static final int NONE= 0;
+	private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER
+	private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC
+	private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC
+	private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC
+	private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC
+	private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
+
+	/** The scanner. */
+	private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000);	// faster implementation
+
+	/** The offset of the last returned token. */
+	private int fTokenOffset;
+	/** The length of the last returned token. */
+	private int fTokenLength;
+
+	/** The state of the scanner. */
+	private int fState;
+	/** The last significant characters read. */
+	private int fLast;
+	/** The amount of characters already read on first call to nextToken(). */
+	private int fPrefixLength;
+
+	// emulate JavaPartitionScanner
+	private boolean fEmulate= false;
+	private int fJavaOffset;
+	private int fJavaLength;
+
+	private final IToken[] fTokens= new IToken[] {
+		new Token(null),
+		new Token(JAVA_SINGLE_LINE_COMMENT),
+		new Token(JAVA_MULTI_LINE_COMMENT),
+		new Token(JAVA_DOC),
+		new Token(JAVA_CHARACTER),
+		new Token(JAVA_STRING)
+	};
+
+	public FastJavaPartitionScanner(boolean emulate) {
+	    fEmulate= emulate;
+	}
+
+	public FastJavaPartitionScanner() {
+	    this(false);
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+	 */
+	public IToken nextToken() {
+
+		// emulate JavaPartitionScanner
+		if (fEmulate) {
+			if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) {
+				fTokenOffset += fTokenLength;
+				return fTokens[JAVA];
+			} else {
+				fJavaOffset= -1;
+				fJavaLength= 0;
+			}
+		}
+
+		fTokenOffset += fTokenLength;
+		fTokenLength= fPrefixLength;
+
+		while (true) {
+			final int ch= fScanner.read();
+
+			// characters
+	 		switch (ch) {
+	 		case ICharacterScanner.EOF:
+		 		if (fTokenLength > 0) {
+		 			fLast= NONE; // ignore last
+		 			return preFix(fState, JAVA, NONE, 0);
+
+		 		} else {
+		 			fLast= NONE;
+		 			fPrefixLength= 0;
+					return Token.EOF;
+		 		}
+
+	 		case '\r':
+	 			// emulate JavaPartitionScanner
+	 			if (!fEmulate && fLast != CARRIAGE_RETURN) {
+						fLast= CARRIAGE_RETURN;
+						fTokenLength++;
+	 					continue;
+
+	 			} else {
+
+					switch (fState) {
+					case SINGLE_LINE_COMMENT:
+					case CHARACTER:
+					case STRING:
+						if (fTokenLength > 0) {
+							IToken token= fTokens[fState];
+
+				 			// emulate JavaPartitionScanner
+							if (fEmulate) {
+								fTokenLength++;
+								fLast= NONE;
+								fPrefixLength= 0;
+							} else {
+								fLast= CARRIAGE_RETURN;
+								fPrefixLength= 1;
+							}
+
+							fState= JAVA;
+							return token;
+
+						} else {
+							consume();
+							continue;
+						}
+
+					default:
+						consume();
+						continue;
+					}
+	 			}
+
+	 		case '\n':
+				switch (fState) {
+				case SINGLE_LINE_COMMENT:
+				case CHARACTER:
+				case STRING:
+					// assert(fTokenLength > 0);
+					return postFix(fState);
+
+				default:
+					consume();
+					continue;
+				}
+
+			default:
+				if (!fEmulate && fLast == CARRIAGE_RETURN) {
+					switch (fState) {
+					case SINGLE_LINE_COMMENT:
+					case CHARACTER:
+					case STRING:
+
+						int last;
+						int newState;
+						switch (ch) {
+						case '/':
+							last= SLASH;
+							newState= JAVA;
+							break;
+
+						case '*':
+							last= STAR;
+							newState= JAVA;
+							break;
+
+						case '\'':
+							last= NONE;
+							newState= CHARACTER;
+							break;
+
+						case '"':
+							last= NONE;
+							newState= STRING;
+							break;
+
+						case '\r':
+							last= CARRIAGE_RETURN;
+							newState= JAVA;
+							break;
+
+						case '\\':
+							last= BACKSLASH;
+							newState= JAVA;
+							break;
+
+						default:
+							last= NONE;
+							newState= JAVA;
+							break;
+						}
+
+						fLast= NONE; // ignore fLast
+						return preFix(fState, newState, last, 1);
+
+					default:
+						break;
+					}
+				}
+			}
+
+			// states
+	 		switch (fState) {
+	 		case JAVA:
+				switch (ch) {
+				case '/':
+					if (fLast == SLASH) {
+						if (fTokenLength - getLastLength(fLast) > 0) {
+							return preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
+						} else {
+							preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
+							fTokenOffset += fTokenLength;
+							fTokenLength= fPrefixLength;
+							break;
+						}
+
+					} else {
+						fTokenLength++;
+						fLast= SLASH;
+						break;
+					}
+
+				case '*':
+					if (fLast == SLASH) {
+						if (fTokenLength - getLastLength(fLast) > 0)
+							return preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+						else {
+							preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+							fTokenOffset += fTokenLength;
+							fTokenLength= fPrefixLength;
+							break;
+						}
+
+					} else {
+						consume();
+						break;
+					}
+
+				case '\'':
+					fLast= NONE; // ignore fLast
+					if (fTokenLength > 0)
+						return preFix(JAVA, CHARACTER, NONE, 1);
+					else {
+						preFix(JAVA, CHARACTER, NONE, 1);
+						fTokenOffset += fTokenLength;
+						fTokenLength= fPrefixLength;
+						break;
+					}
+
+				case '"':
+					fLast= NONE; // ignore fLast
+					if (fTokenLength > 0)
+						return preFix(JAVA, STRING, NONE, 1);
+					else {
+						preFix(JAVA, STRING, NONE, 1);
+						fTokenOffset += fTokenLength;
+						fTokenLength= fPrefixLength;
+						break;
+					}
+
+				default:
+					consume();
+					break;
+				}
+				break;
+
+	 		case SINGLE_LINE_COMMENT:
+				consume();
+				break;
+
+	 		case JAVADOC:
+				switch (ch) {
+				case '/':
+					switch (fLast) {
+					case SLASH_STAR_STAR:
+						return postFix(MULTI_LINE_COMMENT);
+
+					case STAR:
+						return postFix(JAVADOC);
+
+					default:
+						consume();
+						break;
+					}
+					break;
+
+				case '*':
+					fTokenLength++;
+					fLast= STAR;
+					break;
+
+				default:
+					consume();
+					break;
+				}
+				break;
+
+	 		case MULTI_LINE_COMMENT:
+				switch (ch) {
+				case '*':
+					if (fLast == SLASH_STAR) {
+						fLast= SLASH_STAR_STAR;
+						fTokenLength++;
+						fState= JAVADOC;
+					} else {
+						fTokenLength++;
+						fLast= STAR;
+					}
+					break;
+
+				case '/':
+					if (fLast == STAR) {
+						return postFix(MULTI_LINE_COMMENT);
+					} else {
+						consume();
+						break;
+					}
+
+				default:
+					consume();
+					break;
+				}
+				break;
+
+	 		case STRING:
+	 			switch (ch) {
+	 			case '\\':
+					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+					fTokenLength++;
+					break;
+
+				case '\"':
+	 				if (fLast != BACKSLASH) {
+	 					return postFix(STRING);
+
+		 			} else {
+						consume();
+						break;
+	 				}
+
+		 		default:
+					consume();
+	 				break;
+	 			}
+	 			break;
+
+	 		case CHARACTER:
+	 			switch (ch) {
+				case '\\':
+					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+					fTokenLength++;
+					break;
+
+	 			case '\'':
+	 				if (fLast != BACKSLASH) {
+	 					return postFix(CHARACTER);
+
+	 				} else {
+						consume();
+		 				break;
+	 				}
+
+	 			default:
+					consume();
+	 				break;
+	 			}
+	 			break;
+	 		}
+		}
+ 	}
+
+	private static final int getLastLength(int last) {
+		switch (last) {
+		default:
+			return -1;
+
+		case NONE:
+			return 0;
+
+		case CARRIAGE_RETURN:
+		case BACKSLASH:
+		case SLASH:
+		case STAR:
+			return 1;
+
+		case SLASH_STAR:
+			return 2;
+
+		case SLASH_STAR_STAR:
+			return 3;
+		}
+	}
+
+	private final void consume() {
+		fTokenLength++;
+		fLast= NONE;
+	}
+
+	private final IToken postFix(int state) {
+		fTokenLength++;
+		fLast= NONE;
+		fState= JAVA;
+		fPrefixLength= 0;
+		return fTokens[state];
+	}
+
+	private final IToken preFix(int state, int newState, int last, int prefixLength) {
+		// emulate JavaPartitionScanner
+		if (fEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) {
+			fTokenLength -= getLastLength(fLast);
+			fJavaOffset= fTokenOffset;
+			fJavaLength= fTokenLength;
+			fTokenLength= 1;
+			fState= newState;
+			fPrefixLength= prefixLength;
+			fLast= last;
+			return fTokens[state];
+
+		} else {
+			fTokenLength -= getLastLength(fLast);
+			fLast= last;
+			fPrefixLength= prefixLength;
+			IToken token= fTokens[state];
+			fState= newState;
+			return token;
+		}
+	}
+
+	private static int getState(String contentType) {
+
+		if (contentType == null)
+			return JAVA;
+
+		else if (contentType.equals(JAVA_SINGLE_LINE_COMMENT))
+			return SINGLE_LINE_COMMENT;
+
+		else if (contentType.equals(JAVA_MULTI_LINE_COMMENT))
+			return MULTI_LINE_COMMENT;
+
+		else if (contentType.equals(JAVA_DOC))
+			return JAVADOC;
+
+		else if (contentType.equals(JAVA_STRING))
+			return STRING;
+
+		else if (contentType.equals(JAVA_CHARACTER))
+			return CHARACTER;
+
+		else
+			return JAVA;
+	}
+
+	/*
+	 * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
+	 */
+	public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+
+		fScanner.setRange(document, offset, length);
+		fTokenOffset= partitionOffset;
+		fTokenLength= 0;
+		fPrefixLength= offset - partitionOffset;
+		fLast= NONE;
+
+		if (offset == partitionOffset) {
+			// restart at beginning of partition
+			fState= JAVA;
+		} else {
+			fState= getState(contentType);
+		}
+
+		// emulate JavaPartitionScanner
+		if (fEmulate) {
+			fJavaOffset= -1;
+			fJavaLength= 0;
+		}
+	}
+
+	/*
+	 * @see ITokenScanner#setRange(IDocument, int, int)
+	 */
+	public void setRange(IDocument document, int offset, int length) {
+
+		fScanner.setRange(document, offset, length);
+		fTokenOffset= offset;
+		fTokenLength= 0;
+		fPrefixLength= 0;
+		fLast= NONE;
+		fState= JAVA;
+
+		// emulate JavaPartitionScanner
+		if (fEmulate) {
+			fJavaOffset= -1;
+			fJavaLength= 0;
+		}
+	}
+
+	/*
+	 * @see ITokenScanner#getTokenLength()
+	 */
+	public int getTokenLength() {
+		return fTokenLength;
+	}
+
+	/*
+	 * @see ITokenScanner#getTokenOffset()
+	 */
+	public int getTokenOffset() {
+		return fTokenOffset;
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManager.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManager.java
new file mode 100644
index 0000000..aa08930
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManager.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.source.ISharedTextColors;
+import org.eclipse.swt.graphics.Color;
+
+
+/**
+ * Manages SWT color objects for the given color keys and
+ * given <code>RGB</code> objects. Until the <code>dispose</code>
+ * method is called, the same color object is returned for
+ * equal keys and equal <code>RGB</code> values.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IColorManager</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManagerExtension} since version 2.0 introducing
+ * 		the ability to bind and un-bind colors.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManagerExtension
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IJavaColorConstants
+ */
+public interface IColorManager extends ISharedTextColors {
+
+	/**
+	 * Returns a color object for the given key. The color objects
+	 * are remembered internally; the same color object is returned
+	 * for equal keys.
+	 *
+	 * @param key the color key
+	 * @return the color object for the given key
+	 */
+	Color getColor(String key);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManagerExtension.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManagerExtension.java
new file mode 100644
index 0000000..b266f84
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManagerExtension.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.swt.graphics.RGB;
+
+
+/**
+ * Extends {@link org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManager} with
+ * the ability to bind and un-bind colors.
+ *
+ * @since 2.0
+ */
+public interface IColorManagerExtension {
+
+	/**
+	 * Remembers the given color specification under the given key.
+	 *
+	 * @param key the color key
+	 * @param rgb the color specification
+	 * @throws java.lang.UnsupportedOperationException if there is already a
+	 * 	color specification remembered under the given key
+	 */
+	void bindColor(String key, RGB rgb);
+
+
+	/**
+	 * Forgets the color specification remembered under the given key.
+	 *
+	 * @param key the color key
+	 */
+	void unbindColor(String key);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaColorConstants.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaColorConstants.java
new file mode 100644
index 0000000..d584438
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaColorConstants.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+/**
+ * Color keys used for syntax highlighting Java
+ * code and Javadoc compliant comments.
+ * A <code>IColorManager</code> is responsible for mapping
+ * concrete colors to these keys.
+ * <p>
+ * This interface declares static final fields only; it is not intended to be
+ * implemented.
+ * </p>
+ *
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManager
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManagerExtension
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IJavaColorConstants {
+	/** The color key for Java keywords in Java code
+	 * (value <code>"java_keyword"</code>).
+	 */
+	String JAVA_KEYWORD= "java_keyword"; //$NON-NLS-1$
+	
+	/**
+	 * The color key for everything in Java code for which no other color is specified
+	 * (value <code>"java_default"</code>).
+	 */
+	String JAVA_DEFAULT= "java_default"; //$NON-NLS-1$
+	
+	/** The color key for keyword 'return' in Java code
+	 * (value <code>"java_keyword_return"</code>).
+	 *
+	 * @since 3.0
+	 */
+	String JAVA_KEYWORD_RETURN= "java_keyword_return"; //$NON-NLS-1$
+	
+	/** The color key for operators in Java code
+	 * (value <code>"java_operator"</code>).
+	 *
+	 * @since 3.0
+	 */
+	String JAVA_OPERATOR= "java_operator"; //$NON-NLS-1$
+	
+	/** The color key for brackets in Java code
+	 * (value <code>"java_bracket"</code>).
+	 *
+	 * @since 3.3
+	 */
+	String JAVA_BRACKET= "java_bracket"; //$NON-NLS-1$
+	
+	/**
+	 * The color key for task tags in java comments
+	 * (value <code>"java_comment_task_tag"</code>).
+	 *
+	 * @since 2.1
+	 */
+	String TASK_TAG= "java_comment_task_tag"; //$NON-NLS-1$
+
+	/** The color key for multi-line comments in Java code
+	 * (value <code>"java_multi_line_comment"</code>).
+	 */
+	String JAVA_MULTI_LINE_COMMENT= "java_multi_line_comment"; //$NON-NLS-1$
+
+	/** The color key for single-line comments in Java code
+	 * (value <code>"java_single_line_comment"</code>).
+	 */
+	String JAVA_SINGLE_LINE_COMMENT= "java_single_line_comment"; //$NON-NLS-1$
+	
+	/** The color key for string and character literals in Java code
+	 * (value <code>"java_string"</code>).
+	 */
+	String JAVA_STRING= "java_string"; //$NON-NLS-1$
+
+	/**
+	 * The color key for JavaDoc keywords (<code>@foo</code>) in JavaDoc comments
+	 * (value <code>"java_doc_keyword"</code>).
+	 */
+	String JAVADOC_KEYWORD= "java_doc_keyword"; //$NON-NLS-1$
+
+	/**
+	 * The color key for HTML tags (<code>&lt;foo&gt;</code>) in JavaDoc comments
+	 * (value <code>"java_doc_tag"</code>).
+	 */
+	String JAVADOC_TAG= "java_doc_tag"; //$NON-NLS-1$
+
+	/**
+	 * The color key for JavaDoc links (<code>{foo}</code>) in JavaDoc comments
+	 * (value <code>"java_doc_link"</code>).
+	 */
+	String JAVADOC_LINK= "java_doc_link"; //$NON-NLS-1$
+
+	/**
+	 * The color key for everything in JavaDoc comments for which no other color is specified
+	 * (value <code>"java_doc_default"</code>).
+	 */
+	String JAVADOC_DEFAULT= "java_doc_default"; //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaPartitions.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaPartitions.java
new file mode 100644
index 0000000..c60cce3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaPartitions.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+/**
+ * Definition of Java partitioning and its partitions.
+ *
+ * @since 3.1
+ */
+public interface IJavaPartitions {
+	/**
+	 * The identifier of the Java partitioning.
+	 */
+	String JAVA_PARTITIONING= "___java_partitioning";  //$NON-NLS-1$
+	/**
+	 * The identifier of the single-line (JLS2: EndOfLineComment) end comment partition content type.
+	 */
+	String JAVA_SINGLE_LINE_COMMENT= "__java_singleline_comment"; //$NON-NLS-1$
+
+	/**
+	 * The identifier multi-line (JLS2: TraditionalComment) comment partition content type.
+	 */
+	String JAVA_MULTI_LINE_COMMENT= "__java_multiline_comment"; //$NON-NLS-1$
+	
+	/**
+	 * The identifier of the Javadoc (JLS2: DocumentationComment) partition content type.
+	 */
+	String JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$
+
+	/**
+	 * The identifier of the Java string partition content type.
+	 */
+	String JAVA_STRING= "__java_string"; //$NON-NLS-1$
+
+	/**
+	 * The identifier of the Java character partition content type.
+	 */
+	String JAVA_CHARACTER= "__java_character";  //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/ISourceVersionDependent.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/ISourceVersionDependent.java
new file mode 100644
index 0000000..7f50fcc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/ISourceVersionDependent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+/**
+ * Mix-in for any rule that changes its behavior based on the Java source
+ * version.
+ *
+ * @since 3.1
+ */
+public interface ISourceVersionDependent {
+
+	/**
+	 * Sets the configured java source version to one of the
+	 * <code>JavaCore.VERSION_X_Y</code> values.
+	 *
+	 * @param version the new java source version
+	 * @see org.eclipse.jdt.core.JavaCore
+	 */
+	void setSourceVersion(String version);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCodeScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCodeScanner.java
new file mode 100644
index 0000000..ae73426
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCodeScanner.java
@@ -0,0 +1,553 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Philippe Ombredanne <pombredanne@nexb.com> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=150989
+ *     Anton Leherbauer (Wind River Systems) - [misc] Allow custom token for WhitespaceRule - https://bugs.eclipse.org/bugs/show_bug.cgi?id=251224
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+
+/**
+ * A Java code scanner.
+ */
+public final class JavaCodeScanner extends AbstractJavaScanner {
+
+	/**
+	 * Rule to detect java operators.
+	 *
+	 * @since 3.0
+	 */
+	private static final class OperatorRule implements IRule {
+
+		/** Java operators */
+		private final char[] JAVA_OPERATORS= { ';', '.', '=', '/', '\\', '+', '-', '*', '<', '>', ':', '?', '!', ',', '|', '&', '^', '%', '~'};
+		/** Token to return for this rule */
+		private final IToken fToken;
+
+		/**
+		 * Creates a new operator rule.
+		 *
+		 * @param token Token to use for this rule
+		 */
+		public OperatorRule(IToken token) {
+			fToken= token;
+		}
+
+		/**
+		 * Is this character an operator character?
+		 *
+		 * @param character Character to determine whether it is an operator character
+		 * @return <code>true</code> iff the character is an operator, <code>false</code> otherwise.
+		 */
+		public boolean isOperator(char character) {
+			for (int index= 0; index < JAVA_OPERATORS.length; index++) {
+				if (JAVA_OPERATORS[index] == character)
+					return true;
+			}
+			return false;
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+		 */
+		public IToken evaluate(ICharacterScanner scanner) {
+
+			int character= scanner.read();
+			if (isOperator((char) character)) {
+				do {
+					character= scanner.read();
+				} while (isOperator((char) character));
+				scanner.unread();
+				return fToken;
+			} else {
+				scanner.unread();
+				return Token.UNDEFINED;
+			}
+		}
+	}
+
+	/**
+	 * Rule to detect java brackets.
+	 *
+	 * @since 3.3
+	 */
+	private static final class BracketRule implements IRule {
+
+		/** Java brackets */
+		private final char[] JAVA_BRACKETS= { '(', ')', '{', '}', '[', ']' };
+		/** Token to return for this rule */
+		private final IToken fToken;
+
+		/**
+		 * Creates a new bracket rule.
+		 *
+		 * @param token Token to use for this rule
+		 */
+		public BracketRule(IToken token) {
+			fToken= token;
+		}
+
+		/**
+		 * Is this character a bracket character?
+		 *
+		 * @param character Character to determine whether it is a bracket character
+		 * @return <code>true</code> iff the character is a bracket, <code>false</code> otherwise.
+		 */
+		public boolean isBracket(char character) {
+			for (int index= 0; index < JAVA_BRACKETS.length; index++) {
+				if (JAVA_BRACKETS[index] == character)
+					return true;
+			}
+			return false;
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+		 */
+		public IToken evaluate(ICharacterScanner scanner) {
+
+			int character= scanner.read();
+			if (isBracket((char) character)) {
+				do {
+					character= scanner.read();
+				} while (isBracket((char) character));
+				scanner.unread();
+				return fToken;
+			} else {
+				scanner.unread();
+				return Token.UNDEFINED;
+			}
+		}
+	}
+
+
+	private static class VersionedWordMatcher extends CombinedWordRule.WordMatcher implements ISourceVersionDependent {
+
+		private final IToken fDefaultToken;
+		private final String fVersion;
+		private boolean fIsVersionMatch;
+
+		public VersionedWordMatcher(IToken defaultToken, String version, String currentVersion) {
+			fDefaultToken= defaultToken;
+			fVersion= version;
+			setSourceVersion(currentVersion);
+		}
+
+		/*
+		 * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String)
+		 */
+		public void setSourceVersion(String version) {
+			fIsVersionMatch= fVersion.compareTo(version) <= 0;
+		}
+
+		/*
+		 * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer)
+		 */
+		public IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) {
+			IToken token= super.evaluate(scanner, word);
+
+			if (fIsVersionMatch || token.isUndefined())
+				return token;
+
+			return fDefaultToken;
+		}
+	}
+
+	/**
+	 * An annotation rule matches the '@' symbol, any following whitespace and
+	 * optionally a following <code>interface</code> keyword.
+	 *
+	 * It does not match if there is a comment between the '@' symbol and
+	 * the identifier. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=82452
+	 *
+	 * @since 3.1
+	 */
+	private static class AnnotationRule implements IRule, ISourceVersionDependent {
+		/**
+		 * A resettable scanner supports marking a position in a scanner and
+		 * unreading back to the marked position.
+		 */
+		private static final class ResettableScanner implements ICharacterScanner {
+			private final ICharacterScanner fDelegate;
+			private int fReadCount;
+
+			/**
+			 * Creates a new resettable scanner that will forward calls
+			 * to <code>scanner</code>, but store a marked position.
+			 *
+			 * @param scanner the delegate scanner
+			 */
+			public ResettableScanner(final ICharacterScanner scanner) {
+				Assert.isNotNull(scanner);
+				fDelegate= scanner;
+				mark();
+			}
+
+			/*
+			 * @see org.eclipse.jface.text.rules.ICharacterScanner#getColumn()
+			 */
+			public int getColumn() {
+				return fDelegate.getColumn();
+			}
+
+			/*
+			 * @see org.eclipse.jface.text.rules.ICharacterScanner#getLegalLineDelimiters()
+			 */
+			public char[][] getLegalLineDelimiters() {
+				return fDelegate.getLegalLineDelimiters();
+			}
+
+			/*
+			 * @see org.eclipse.jface.text.rules.ICharacterScanner#read()
+			 */
+			public int read() {
+				int ch= fDelegate.read();
+				if (ch != ICharacterScanner.EOF)
+					fReadCount++;
+				return ch;
+			}
+
+			/*
+			 * @see org.eclipse.jface.text.rules.ICharacterScanner#unread()
+			 */
+			public void unread() {
+				if (fReadCount > 0)
+					fReadCount--;
+				fDelegate.unread();
+			}
+
+			/**
+			 * Marks an offset in the scanned content.
+			 */
+			public void mark() {
+				fReadCount= 0;
+			}
+
+			/**
+			 * Resets the scanner to the marked position.
+			 */
+			public void reset() {
+				while (fReadCount > 0)
+					unread();
+
+				while (fReadCount < 0)
+					read();
+			}
+		}
+
+		private final IWhitespaceDetector fWhitespaceDetector= new JavaWhitespaceDetector();
+		private final IWordDetector fWordDetector= new JavaWordDetector();
+		private final IToken fInterfaceToken;
+		private final IToken fAtToken;
+		private final String fVersion;
+		private boolean fIsVersionMatch;
+
+		/**
+		 * Creates a new rule.
+		 *
+		 * @param interfaceToken the token to return if
+		 *        <code>'@\s*interface'</code> is matched
+		 * @param atToken the token to return if <code>'@'</code>
+		 *        is matched, but not <code>'@\s*interface'</code>
+		 * @param version the lowest <code>JavaCore.COMPILER_SOURCE</code>
+		 *        version that this rule is enabled
+		 * @param currentVersion the current
+		 *        <code>JavaCore.COMPILER_SOURCE</code> version
+		 */
+		public AnnotationRule(IToken interfaceToken, Token atToken, String version, String currentVersion) {
+			fInterfaceToken= interfaceToken;
+			fAtToken= atToken;
+			fVersion= version;
+			setSourceVersion(currentVersion);
+		}
+
+		/*
+		 * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+		 */
+		public IToken evaluate(ICharacterScanner scanner) {
+			if (!fIsVersionMatch)
+				return Token.UNDEFINED;
+
+			ResettableScanner resettable= new ResettableScanner(scanner);
+			if (resettable.read() == '@')
+				return readAnnotation(resettable);
+
+			resettable.reset();
+			return Token.UNDEFINED;
+		}
+
+		private IToken readAnnotation(ResettableScanner scanner) {
+			scanner.mark();
+			skipWhitespace(scanner);
+			if (readInterface(scanner)) {
+				return fInterfaceToken;
+			} else {
+				scanner.reset();
+				return fAtToken;
+			}
+		}
+
+		private boolean readInterface(ICharacterScanner scanner) {
+			int ch= scanner.read();
+			int i= 0;
+			while (i < INTERFACE.length() && INTERFACE.charAt(i) == ch) {
+				i++;
+				ch= scanner.read();
+			}
+			if (i < INTERFACE.length())
+				return false;
+
+			if (fWordDetector.isWordPart((char) ch))
+				return false;
+
+			if (ch != ICharacterScanner.EOF)
+				scanner.unread();
+
+			return true;
+		}
+
+		private boolean skipWhitespace(ICharacterScanner scanner) {
+			while (fWhitespaceDetector.isWhitespace((char) scanner.read())) {
+				// do nothing
+			}
+
+			scanner.unread();
+			return true;
+		}
+
+		/*
+		 * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String)
+		 */
+		public void setSourceVersion(String version) {
+			fIsVersionMatch= fVersion.compareTo(version) <= 0;
+		}
+
+	}
+
+	private static final String SOURCE_VERSION= JavaCore.COMPILER_SOURCE;
+
+	static String[] fgKeywords= {
+		"abstract", //$NON-NLS-1$
+		"break", //$NON-NLS-1$
+		"case", "catch", "class", "const", "continue", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+		"default", "do", //$NON-NLS-2$ //$NON-NLS-1$
+		"else", "extends", //$NON-NLS-2$ //$NON-NLS-1$
+		"final", "finally", "for", //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+		"goto", //$NON-NLS-1$
+		"if", "implements", "import", "instanceof", "interface", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+		"native", "new", //$NON-NLS-2$ //$NON-NLS-1$
+		"package", "private", "protected", "public", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+		"static", "super", "switch", "synchronized", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+		"this", "throw", "throws", "transient", "try", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+		"volatile", //$NON-NLS-1$
+		"while" //$NON-NLS-1$
+	};
+
+	private static final String INTERFACE= "interface";  //$NON-NLS-1$
+	private static final String RETURN= "return"; //$NON-NLS-1$
+	private static String[] fgJava14Keywords= { "assert" }; //$NON-NLS-1$
+	private static String[] fgJava15Keywords= { "enum" }; //$NON-NLS-1$
+
+	private static String[] fgTypes= { "void", "boolean", "char", "byte", "short", "strictfp", "int", "long", "float", "double" }; //$NON-NLS-1$ //$NON-NLS-5$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-8$ //$NON-NLS-9$  //$NON-NLS-10$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-2$
+
+	private static String[] fgConstants= { "false", "null", "true" }; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+	private static final String ANNOTATION_BASE_KEY= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + SemanticHighlightings.ANNOTATION;
+	private static final String ANNOTATION_COLOR_KEY= ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;
+
+	private static String[] fgTokenProperties= {
+		IJavaColorConstants.JAVA_KEYWORD,
+		IJavaColorConstants.JAVA_STRING,
+		IJavaColorConstants.JAVA_DEFAULT,
+		IJavaColorConstants.JAVA_KEYWORD_RETURN,
+		IJavaColorConstants.JAVA_OPERATOR,
+		IJavaColorConstants.JAVA_BRACKET,
+		ANNOTATION_COLOR_KEY,
+	};
+
+	private List<ISourceVersionDependent> fVersionDependentRules= new ArrayList<ISourceVersionDependent>(3);
+
+	/**
+	 * Creates a Java code scanner
+	 *
+	 * @param manager	the color manager
+	 * @param store		the preference store
+	 */
+	public JavaCodeScanner(IColorManager manager, IPreferenceStore store) {
+		super(manager, store);
+		initialize();
+	}
+
+	/*
+	 * @see AbstractJavaScanner#getTokenProperties()
+	 */
+	protected String[] getTokenProperties() {
+		return fgTokenProperties;
+	}
+
+	/*
+	 * @see AbstractJavaScanner#createRules()
+	 */
+	protected List<IRule> createRules() {
+
+		List<IRule> rules= new ArrayList<IRule>();
+
+		// Add rule for character constants.
+		Token token= getToken(IJavaColorConstants.JAVA_STRING);
+		rules.add(new SingleLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+
+
+		Token defaultToken= getToken(IJavaColorConstants.JAVA_DEFAULT);
+		
+		// Add generic whitespace rule.
+		rules.add(new WhitespaceRule(new JavaWhitespaceDetector(), defaultToken));
+
+		String version= getPreferenceStore().getString(SOURCE_VERSION);
+
+		// Add JLS3 rule for /@\s*interface/ and /@\s*\w+/
+		token= getToken(ANNOTATION_COLOR_KEY);
+		AnnotationRule atInterfaceRule= new AnnotationRule(getToken(IJavaColorConstants.JAVA_KEYWORD), token, JavaCore.VERSION_1_5, version);
+		rules.add(atInterfaceRule);
+		fVersionDependentRules.add(atInterfaceRule);
+
+		// Add word rule for new keywords, see bug 4077
+		JavaWordDetector wordDetector= new JavaWordDetector();
+		CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, defaultToken);
+
+		VersionedWordMatcher j14Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_4, version);
+
+		token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+		for (int i=0; i<fgJava14Keywords.length; i++)
+			j14Matcher.addWord(fgJava14Keywords[i], token);
+
+		combinedWordRule.addWordMatcher(j14Matcher);
+		fVersionDependentRules.add(j14Matcher);
+
+		VersionedWordMatcher j15Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_5, version);
+		
+		token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+		for (int i=0; i<fgJava15Keywords.length; i++)
+			j15Matcher.addWord(fgJava15Keywords[i], token);
+
+		combinedWordRule.addWordMatcher(j15Matcher);
+		fVersionDependentRules.add(j15Matcher);
+
+		// Add rule for operators
+		token= getToken(IJavaColorConstants.JAVA_OPERATOR);
+		rules.add(new OperatorRule(token));
+
+		// Add rule for brackets
+		token= getToken(IJavaColorConstants.JAVA_BRACKET);
+		rules.add(new BracketRule(token));
+
+		// Add word rule for keyword 'return'.
+		CombinedWordRule.WordMatcher returnWordRule= new CombinedWordRule.WordMatcher();
+		token= getToken(IJavaColorConstants.JAVA_KEYWORD_RETURN);
+		returnWordRule.addWord(RETURN, token);
+		combinedWordRule.addWordMatcher(returnWordRule);
+
+		// Add word rule for keywords, types, and constants.
+		CombinedWordRule.WordMatcher wordRule= new CombinedWordRule.WordMatcher();
+		token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+		for (int i=0; i<fgKeywords.length; i++)
+			wordRule.addWord(fgKeywords[i], token);
+		for (int i=0; i<fgTypes.length; i++)
+			wordRule.addWord(fgTypes[i], token);
+		for (int i=0; i<fgConstants.length; i++)
+			wordRule.addWord(fgConstants[i], token);
+
+		combinedWordRule.addWordMatcher(wordRule);
+
+		rules.add(combinedWordRule);
+
+		setDefaultReturnToken(defaultToken);
+		return rules;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getBoldKey(java.lang.String)
+	 */
+	protected String getBoldKey(String colorKey) {
+		if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+			return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX;
+		return super.getBoldKey(colorKey);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getItalicKey(java.lang.String)
+	 */
+	protected String getItalicKey(String colorKey) {
+		if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+			return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX;
+		return super.getItalicKey(colorKey);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getStrikethroughKey(java.lang.String)
+	 */
+	protected String getStrikethroughKey(String colorKey) {
+		if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+			return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX;
+		return super.getStrikethroughKey(colorKey);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getUnderlineKey(java.lang.String)
+	 */
+	protected String getUnderlineKey(String colorKey) {
+		if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+			return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX;
+		return super.getUnderlineKey(colorKey);
+	}
+
+	/*
+	 * @see AbstractJavaScanner#affectsBehavior(PropertyChangeEvent)
+	 */
+	public boolean affectsBehavior(PropertyChangeEvent event) {
+		return event.getProperty().equals(SOURCE_VERSION) || super.affectsBehavior(event);
+	}
+
+	/*
+	 * @see AbstractJavaScanner#adaptToPreferenceChange(PropertyChangeEvent)
+	 */
+	public void adaptToPreferenceChange(PropertyChangeEvent event) {
+
+		if (event.getProperty().equals(SOURCE_VERSION)) {
+			Object value= event.getNewValue();
+
+			if (value instanceof String) {
+				String s= (String) value;
+
+				for (Iterator<ISourceVersionDependent> it= fVersionDependentRules.iterator(); it.hasNext();) {
+					ISourceVersionDependent dependent= (ISourceVersionDependent) it.next();
+					dependent.setSourceVersion(s);
+				}
+			}
+
+		} else if (super.affectsBehavior(event)) {
+			super.adaptToPreferenceChange(event);
+		}
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaColorManager.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaColorManager.java
new file mode 100644
index 0000000..6766aff
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaColorManager.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Java color manager.
+ */
+public class JavaColorManager implements IColorManager, IColorManagerExtension {
+
+	protected Map<String,RGB> fKeyTable= new HashMap<String,RGB>(10);
+	protected Map<Display,Map<RGB,Color>> fDisplayTable= new HashMap<Display,Map<RGB,Color>>(2);
+
+	/**
+	 * Flag which tells if the colors are automatically disposed when
+	 * the current display gets disposed.
+	 */
+	private boolean fAutoDisposeOnDisplayDispose;
+
+
+	/**
+	 * Creates a new Java color manager which automatically
+	 * disposes the allocated colors when the current display
+	 * gets disposed.
+	 */
+	public JavaColorManager() {
+		this(true);
+	}
+
+	/**
+	 * Creates a new Java color manager.
+	 *
+	 * @param autoDisposeOnDisplayDispose 	if <code>true</code>  the color manager
+	 * automatically disposes all managed colors when the current display gets disposed
+	 * and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()} are ignored.
+	 *
+	 * @since 2.1
+	 */
+	public JavaColorManager(boolean autoDisposeOnDisplayDispose) {
+		fAutoDisposeOnDisplayDispose= autoDisposeOnDisplayDispose;
+	}
+
+	public void dispose(Display display) {
+		Map<RGB,Color> colorTable= fDisplayTable.get(display);
+		if (colorTable != null) {
+			Iterator<Color> e= colorTable.values().iterator();
+			while (e.hasNext()) {
+				Color color= (Color)e.next();
+				if (color != null && !color.isDisposed())
+					color.dispose();
+			}
+		}
+	}
+
+	/*
+	 * @see IColorManager#getColor(RGB)
+	 */
+	public Color getColor(RGB rgb) {
+
+		if (rgb == null)
+			return null;
+
+		final Display display= Display.getCurrent();
+		Map<RGB,Color> colorTable= fDisplayTable.get(display);
+		if (colorTable == null) {
+			colorTable= new HashMap<RGB,Color>(10);
+			fDisplayTable.put(display, colorTable);
+			if (fAutoDisposeOnDisplayDispose) {
+				display.disposeExec(new Runnable() {
+					public void run() {
+						dispose(display);
+					}
+				});
+			}
+		}
+
+		Color color= (Color) colorTable.get(rgb);
+		if (color == null) {
+			color= new Color(Display.getCurrent(), rgb);
+			colorTable.put(rgb, color);
+		}
+
+		return color;
+	}
+
+	/*
+	 * @see IColorManager#dispose
+	 */
+	public void dispose() {
+		if (!fAutoDisposeOnDisplayDispose)
+			dispose(Display.getCurrent());
+	}
+
+	/*
+	 * @see IColorManager#getColor(String)
+	 */
+	public Color getColor(String key) {
+
+		if (key == null)
+			return null;
+
+		RGB rgb= (RGB) fKeyTable.get(key);
+		return getColor(rgb);
+	}
+
+	/*
+	 * @see IColorManagerExtension#bindColor(String, RGB)
+	 */
+	public void bindColor(String key, RGB rgb) {
+		Object value= fKeyTable.get(key);
+		if (value != null)
+			throw new UnsupportedOperationException();
+
+		fKeyTable.put(key, rgb);
+	}
+
+	/*
+	 * @see IColorManagerExtension#unbindColor(String)
+	 */
+	public void unbindColor(String key) {
+		fKeyTable.remove(key);
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCommentScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCommentScanner.java
new file mode 100644
index 0000000..3325a38
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCommentScanner.java
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Michel Ishizuka <cqw10305@nifty.com> - Bug 113266 [syntax highlighting] javadoc tag names including period is not highlighting correctly
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.CombinedWordRule.WordMatcher;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+
+/**
+ * Java comment scanner.
+ */
+public class JavaCommentScanner extends AbstractJavaScanner{
+
+	private static class AtJavaIdentifierDetector implements IWordDetector {
+
+		public boolean isWordStart(char c) {
+			return c == '@' || Character.isJavaIdentifierStart(c);
+		}
+
+		public boolean isWordPart(char c) {
+			return c == '.' || Character.isJavaIdentifierPart(c);
+		}
+	}
+
+	private class TaskTagMatcher extends CombinedWordRule.WordMatcher {
+
+		private IToken fToken;
+		/**
+		 * Uppercase words
+		 * @since 3.0
+		 */
+		private Map<CombinedWordRule.CharacterBuffer,IToken> fUppercaseWords= new HashMap<CombinedWordRule.CharacterBuffer,IToken>();
+		/**
+		 * <code>true</code> if task tag detection is case-sensitive.
+		 * @since 3.0
+		 */
+		private boolean fCaseSensitive= true;
+		/**
+		 * Buffer for uppercase word
+		 * @since 3.0
+		 */
+		private CombinedWordRule.CharacterBuffer fBuffer= new CombinedWordRule.CharacterBuffer(16);
+
+		public TaskTagMatcher(IToken token) {
+			fToken= token;
+		}
+
+		/*
+		 * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#clearWords()
+		 * @since 3.0
+		 */
+		public synchronized void clearWords() {
+			super.clearWords();
+			fUppercaseWords.clear();
+		}
+
+		public synchronized void addTaskTags(String value) {
+			String[] tasks= split(value, ","); //$NON-NLS-1$
+			for (int i= 0; i < tasks.length; i++) {
+				if (tasks[i].length() > 0) {
+					addWord(tasks[i], fToken);
+				}
+			}
+		}
+
+		private String[] split(String value, String delimiters) {
+			StringTokenizer tokenizer= new StringTokenizer(value, delimiters);
+			int size= tokenizer.countTokens();
+			String[] tokens= new String[size];
+			int i= 0;
+			while (i < size)
+				tokens[i++]= tokenizer.nextToken();
+			return tokens;
+		}
+
+		/*
+		 * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#addWord(java.lang.String, org.eclipse.jface.text.rules.IToken)
+		 * @since 3.0
+		 */
+		public synchronized void addWord(String word, IToken token) {
+			Assert.isNotNull(word);
+			Assert.isNotNull(token);
+
+			super.addWord(word, token);
+			fUppercaseWords.put(new CombinedWordRule.CharacterBuffer(word.toUpperCase()), token);
+		}
+
+		/*
+		 * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer)
+		 * @since 3.0
+		 */
+		public synchronized IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) {
+			if (fCaseSensitive)
+				return super.evaluate(scanner, word);
+
+			fBuffer.clear();
+			for (int i= 0, n= word.length(); i < n; i++)
+				fBuffer.append(Character.toUpperCase(word.charAt(i)));
+
+			IToken token= (IToken) fUppercaseWords.get(fBuffer);
+			if (token != null)
+				return token;
+			return Token.UNDEFINED;
+		}
+
+		/**
+		 * Enables/disables the case-sensitivity of the task tag detection.
+		 *
+		 * @param caseSensitive <code>true</code> iff case-sensitivity should be enabled
+		 * @since 3.0
+		 */
+		public void setCaseSensitive(boolean caseSensitive) {
+			fCaseSensitive= caseSensitive;
+		}
+	}
+
+	private static final String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
+	protected static final String TASK_TAG = IJavaColorConstants.TASK_TAG;
+	/**
+	 * Preference key of a string preference, specifying if task tag detection is case-sensitive.
+	 * @since 3.0
+	 */
+	private static final String COMPILER_TASK_CASE_SENSITIVE= JavaCore.COMPILER_TASK_CASE_SENSITIVE;
+	/**
+	 * Preference value of enabled preferences.
+	 * @since 3.0
+	 */
+	private static final String ENABLED= JavaCore.ENABLED;
+
+	private TaskTagMatcher fTaskTagMatcher;
+	private String fDefaultTokenProperty;
+	private String[] fTokenProperties;
+
+	public JavaCommentScanner(IColorManager manager, IPreferenceStore store, String defaultTokenProperty) {
+		this(manager, store, defaultTokenProperty, new String[] { defaultTokenProperty, TASK_TAG });
+	}
+
+	public JavaCommentScanner(IColorManager manager, IPreferenceStore store, String defaultTokenProperty, String[] tokenProperties) {
+		super(manager, store);
+
+		fDefaultTokenProperty= defaultTokenProperty;
+		fTokenProperties= tokenProperties;
+
+		initialize();
+	}
+
+	/*
+	 * @see AbstractJavaScanner#createRules()
+	 */
+	protected List<IRule> createRules() {
+		List<IRule> list= new ArrayList<IRule>();
+		Token defaultToken= getToken(fDefaultTokenProperty);
+
+		List<WordMatcher> matchers= createMatchers();
+		if (matchers.size() > 0) {
+			CombinedWordRule combinedWordRule= new CombinedWordRule(new AtJavaIdentifierDetector(), defaultToken);
+			for (int i= 0, n= matchers.size(); i < n; i++)
+				combinedWordRule.addWordMatcher((WordMatcher) matchers.get(i));
+			list.add(combinedWordRule);
+		}
+
+		setDefaultReturnToken(defaultToken);
+
+		return list;
+	}
+
+	/**
+	 * Creates a list of word matchers.
+	 *
+	 * @return the list of word matchers
+	 */
+	protected List<WordMatcher> createMatchers() {
+		List<WordMatcher> list= new ArrayList<WordMatcher>();
+
+		// Add rule for Task Tags.
+		boolean isCaseSensitive= true;
+		String tasks= null;
+		if (getPreferenceStore().contains(COMPILER_TASK_TAGS)) {
+			tasks= getPreferenceStore().getString(COMPILER_TASK_TAGS);
+			isCaseSensitive= ENABLED.equals(getPreferenceStore().getString(COMPILER_TASK_CASE_SENSITIVE));
+		}
+		if (tasks != null) {
+			fTaskTagMatcher= new TaskTagMatcher(getToken(TASK_TAG));
+			fTaskTagMatcher.addTaskTags(tasks);
+			fTaskTagMatcher.setCaseSensitive(isCaseSensitive);
+			list.add(fTaskTagMatcher);
+		}
+
+		return list;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#affectsBehavior(org.eclipse.jface.util.PropertyChangeEvent)
+	 */
+	public boolean affectsBehavior(PropertyChangeEvent event) {
+		return event.getProperty().equals(COMPILER_TASK_TAGS) || event.getProperty().equals(COMPILER_TASK_CASE_SENSITIVE) || super.affectsBehavior(event);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#adaptToPreferenceChange(org.eclipse.jface.util.PropertyChangeEvent)
+	 */
+	public void adaptToPreferenceChange(PropertyChangeEvent event) {
+		if (fTaskTagMatcher != null && event.getProperty().equals(COMPILER_TASK_TAGS)) {
+			Object value= event.getNewValue();
+			if (value instanceof String) {
+				synchronized (fTaskTagMatcher) {
+					fTaskTagMatcher.clearWords();
+					fTaskTagMatcher.addTaskTags((String) value);
+				}
+			}
+		} else if (fTaskTagMatcher != null && event.getProperty().equals(COMPILER_TASK_CASE_SENSITIVE)) {
+			Object value= event.getNewValue();
+			if (value instanceof String)
+				fTaskTagMatcher.setCaseSensitive(ENABLED.equals(value));
+		} else if (super.affectsBehavior(event))
+			super.adaptToPreferenceChange(event);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getTokenProperties()
+	 */
+	protected String[] getTokenProperties() {
+		return fTokenProperties;
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaDocScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaDocScanner.java
new file mode 100644
index 0000000..66f95d9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaDocScanner.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Anton Leherbauer (Wind River Systems) - [misc] Allow custom token for WhitespaceRule - https://bugs.eclipse.org/bugs/show_bug.cgi?id=251224
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.CombinedWordRule.CharacterBuffer;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.CombinedWordRule.WordMatcher;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * A rule based JavaDoc scanner.
+ */
+public final class JavaDocScanner extends JavaCommentScanner {
+
+
+	/**
+	 * Detector for HTML comment delimiters.
+	 */
+	static class HTMLCommentDetector implements IWordDetector {
+
+		/**
+		 * @see IWordDetector#isWordStart(char)
+		 */
+		public boolean isWordStart(char c) {
+			return (c == '<' || c == '-');
+		}
+
+		/**
+		 * @see IWordDetector#isWordPart(char)
+		 */
+		public boolean isWordPart(char c) {
+			return (c == '-' || c == '!' || c == '>');
+		}
+	}
+
+	class TagRule extends SingleLineRule {
+
+		/*
+		 * @see SingleLineRule
+		 */
+		public TagRule(IToken token) {
+			super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
+		}
+
+		/*
+		 * @see SingleLineRule
+		 */
+		public TagRule(IToken token, char escapeCharacter) {
+			super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
+		}
+
+		private IToken evaluateToken() {
+			try {
+				final String token= getDocument().get(getTokenOffset(), getTokenLength()) + "."; //$NON-NLS-1$
+
+				int offset= 0;
+				char character= token.charAt(++offset);
+
+				if (character == '/')
+					character= token.charAt(++offset);
+
+				while (Character.isWhitespace(character))
+					character= token.charAt(++offset);
+
+				while (Character.isLetterOrDigit(character))
+					character= token.charAt(++offset);
+
+				while (Character.isWhitespace(character))
+					character= token.charAt(++offset);
+
+				if (offset >= 2 && token.charAt(offset) == fEndSequence[0])
+					return fToken;
+
+			} catch (BadLocationException exception) {
+				// Do nothing
+			}
+			return getToken(IJavaColorConstants.JAVADOC_DEFAULT);
+		}
+
+		/*
+		 * @see PatternRule#evaluate(ICharacterScanner)
+		 */
+		public IToken evaluate(ICharacterScanner scanner) {
+			IToken result= super.evaluate(scanner);
+			if (result == fToken)
+				return evaluateToken();
+			return result;
+		}
+	}
+
+	private static String[] fgTokenProperties= {
+		IJavaColorConstants.JAVADOC_KEYWORD,
+		IJavaColorConstants.JAVADOC_TAG,
+		IJavaColorConstants.JAVADOC_LINK,
+		IJavaColorConstants.JAVADOC_DEFAULT,
+		TASK_TAG
+	};
+
+
+	public JavaDocScanner(IColorManager manager, IPreferenceStore store) {
+		super(manager, store, IJavaColorConstants.JAVADOC_DEFAULT, fgTokenProperties);
+	}
+
+
+	public IDocument getDocument() {
+		return fDocument;
+	}
+
+	/*
+	 * @see AbstractJavaScanner#createRules()
+	 */
+	protected List<IRule> createRules() {
+
+		List<IRule> list= new ArrayList<IRule>();
+
+		// Add rule for tags.
+		Token token= getToken(IJavaColorConstants.JAVADOC_TAG);
+		list.add(new TagRule(token));
+
+
+		// Add rule for HTML comments
+		WordRule wordRule= new WordRule(new HTMLCommentDetector(), token);
+		wordRule.addWord("<!--", token); //$NON-NLS-1$
+		wordRule.addWord("--!>", token); //$NON-NLS-1$
+		list.add(wordRule);
+
+
+		// Add rule for links.
+		token= getToken(IJavaColorConstants.JAVADOC_LINK);
+		list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+		list.add(new SingleLineRule("{@value", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+		list.add(new SingleLineRule("{@inheritDoc", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+
+
+		// Add generic whitespace rule.
+		token= getToken(IJavaColorConstants.JAVADOC_DEFAULT);
+		list.add(new WhitespaceRule(new JavaWhitespaceDetector(), token));
+
+
+		list.addAll(super.createRules());
+		return list;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.JavaCommentScanner#createMatchers()
+	 */
+	protected List<WordMatcher> createMatchers() {
+		List<WordMatcher> list= super.createMatchers();
+
+		// Add word rule for keywords.
+		final IToken token= getToken(IJavaColorConstants.JAVADOC_KEYWORD);
+		WordMatcher matcher= new WordMatcher() { 
+			public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) {
+				int length= word.length();
+				if (length > 1 && word.charAt(0) == '@') {
+					int i= 0;
+					try {
+						for (; i <= length; i++)
+							scanner.unread();
+						int c= scanner.read();
+						i--;
+						if (c == '*' || Character.isWhitespace((char)c)) {
+							scanner.unread();
+							return token;
+						}
+					} finally {
+						for (; i >= 0; i--)
+							scanner.read();
+					}
+				}
+				return Token.UNDEFINED;
+			}
+		};
+		list.add(matcher);
+
+		return list;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaPresentationReconciler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaPresentationReconciler.java
new file mode 100644
index 0000000..dc53042
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaPresentationReconciler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+
+
+/**
+ * Presentation reconciler, adding functionality for operation without a viewer.
+ *
+ * @since 3.0
+ */
+public class JavaPresentationReconciler extends PresentationReconciler {
+
+	/** Last used document */
+	private IDocument fLastDocument;
+
+	/**
+	 * Constructs a "repair description" for the given damage and returns
+	 * this description as a text presentation.
+	 * <p>
+	 * NOTE: Should not be used if this reconciler is installed on a viewer.
+	 * </p>
+	 *
+	 * @param damage the damage to be repaired
+	 * @param document the document whose presentation must be repaired
+	 * @return the presentation repair description as text presentation
+	 */
+	public TextPresentation createRepairDescription(IRegion damage, IDocument document) {
+		if (document != fLastDocument) {
+			setDocumentToDamagers(document);
+			setDocumentToRepairers(document);
+			fLastDocument= document;
+		}
+		return createPresentation(damage, document);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaSourceViewerConfiguration.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaSourceViewerConfiguration.java
new file mode 100644
index 0000000..43aa2b7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaSourceViewerConfiguration.java
@@ -0,0 +1,65 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class JavaSourceViewerConfiguration extends SourceViewerConfiguration {
+	private JavaTextTools textTools;
+
+	public JavaSourceViewerConfiguration(JavaTextTools textTools) {
+		this.textTools = textTools;
+	}
+	
+	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+		return new String[] {
+				IDocument.DEFAULT_CONTENT_TYPE, 
+				IJavaPartitions.JAVA_DOC,
+				IJavaPartitions.JAVA_MULTI_LINE_COMMENT,
+				IJavaPartitions.JAVA_SINGLE_LINE_COMMENT,
+				IJavaPartitions.JAVA_STRING,
+				IJavaPartitions.JAVA_CHARACTER
+		};
+	}
+	
+	@Override
+	public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+		return IJavaPartitions.JAVA_PARTITIONING;
+	}
+	
+	@Override
+	public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+		PresentationReconciler reconciler= new JavaPresentationReconciler();
+		reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+		
+		DefaultDamagerRepairer dr= new DefaultDamagerRepairer(textTools.getCodeScanner());
+		reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+		reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+		dr= new DefaultDamagerRepairer(textTools.getJavaDocScanner());
+		reconciler.setDamager(dr, IJavaPartitions.JAVA_DOC);
+		reconciler.setRepairer(dr, IJavaPartitions.JAVA_DOC);
+
+		dr= new DefaultDamagerRepairer(textTools.getMultilineCommentScanner());
+		reconciler.setDamager(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
+		reconciler.setRepairer(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
+
+		dr= new DefaultDamagerRepairer(textTools.getSinglelineCommentScanner());
+		reconciler.setDamager(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
+		reconciler.setRepairer(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
+
+		dr= new DefaultDamagerRepairer(textTools.getStringScanner());
+		reconciler.setDamager(dr, IJavaPartitions.JAVA_STRING);
+		reconciler.setRepairer(dr, IJavaPartitions.JAVA_STRING);
+
+		dr= new DefaultDamagerRepairer(textTools.getStringScanner());
+		reconciler.setDamager(dr, IJavaPartitions.JAVA_CHARACTER);
+		reconciler.setRepairer(dr, IJavaPartitions.JAVA_CHARACTER);
+
+
+		return reconciler;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaTextTools.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaTextTools.java
new file mode 100644
index 0000000..76ab9bf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaTextTools.java
@@ -0,0 +1,148 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+public class JavaTextTools {
+	/**
+	 * Array with legal content types.
+	 * @since 3.0
+	 */
+	private final static String[] LEGAL_CONTENT_TYPES= new String[] {
+		IJavaPartitions.JAVA_DOC,
+		IJavaPartitions.JAVA_MULTI_LINE_COMMENT,
+		IJavaPartitions.JAVA_SINGLE_LINE_COMMENT,
+		IJavaPartitions.JAVA_STRING,
+		IJavaPartitions.JAVA_CHARACTER
+	};
+
+	/**
+	 * This tools' preference listener.
+	 */
+	private class PreferenceListener implements IPropertyChangeListener {
+		public void propertyChange(PropertyChangeEvent event) {
+			adaptToPreferenceChange(event);
+		}
+	}
+	
+	/** The color manager. */
+	private JavaColorManager fColorManager;
+	/** The Java source code scanner. */
+	private JavaCodeScanner fCodeScanner;
+	/** The Java multi-line comment scanner. */
+	private JavaCommentScanner fMultilineCommentScanner;
+	/** The Java single-line comment scanner. */
+	private JavaCommentScanner fSinglelineCommentScanner;
+	/** The Java string scanner. */
+	private SingleTokenJavaScanner fStringScanner;
+	/** The JavaDoc scanner. */
+	private JavaDocScanner fJavaDocScanner;
+	/** The preference store. */
+	private IPreferenceStore fPreferenceStore;
+	
+	/**
+	 * The core preference store.
+	 * @since 2.1
+	 */
+	/** The preference change listener */
+	private PreferenceListener fPreferenceListener= new PreferenceListener();
+
+	public JavaTextTools(IPreferenceStore store, boolean autoDisposeOnDisplayDispose) {
+		fPreferenceStore = store;
+		fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
+		
+		fColorManager= new JavaColorManager(autoDisposeOnDisplayDispose);
+		fCodeScanner= new JavaCodeScanner(fColorManager, store);
+		fMultilineCommentScanner= new JavaCommentScanner(fColorManager, store, IJavaColorConstants.JAVA_MULTI_LINE_COMMENT);
+		fSinglelineCommentScanner= new JavaCommentScanner(fColorManager, store, IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT);
+		fStringScanner= new SingleTokenJavaScanner(fColorManager, store, IJavaColorConstants.JAVA_STRING);
+		fJavaDocScanner= new JavaDocScanner(fColorManager, store);
+	}
+	
+	public ITokenScanner getMultilineCommentScanner() {
+		return fMultilineCommentScanner;
+	}
+	
+	public ITokenScanner getSinglelineCommentScanner() {
+		return fSinglelineCommentScanner;
+	}
+	
+	public ITokenScanner getStringScanner() {
+		return fStringScanner;
+	}
+	
+	public ITokenScanner getJavaDocScanner() {
+		return fJavaDocScanner;
+	}
+	
+	public ITokenScanner getCodeScanner() {
+		return fCodeScanner;
+	}
+	
+	/**
+	 * Sets up the Java document partitioner for the given document for the given partitioning.
+	 *
+	 * @param document the document to be set up
+	 * @param partitioning the document partitioning
+	 * @since 3.0
+	 */
+	public void setupJavaDocumentPartitioner(IDocument document, String partitioning) {
+		IDocumentPartitioner partitioner= createDocumentPartitioner();
+		if (document instanceof IDocumentExtension3) {
+			IDocumentExtension3 extension3= (IDocumentExtension3) document;
+			extension3.setDocumentPartitioner(partitioning, partitioner);
+		} else {
+			document.setDocumentPartitioner(partitioner);
+		}
+		partitioner.connect(document);
+	}
+	
+	/**
+	 * Returns a scanner which is configured to scan
+	 * Java-specific partitions, which are multi-line comments,
+	 * Javadoc comments, and regular Java source code.
+	 *
+	 * @return a Java partition scanner
+	 */
+	public IPartitionTokenScanner getPartitionScanner() {
+		return new FastJavaPartitionScanner();
+	}
+
+	/**
+	 * Factory method for creating a Java-specific document partitioner
+	 * using this object's partitions scanner. This method is a
+	 * convenience method.
+	 *
+	 * @return a newly created Java document partitioner
+	 */
+	public IDocumentPartitioner createDocumentPartitioner() {
+		return new FastPartitioner(getPartitionScanner(), LEGAL_CONTENT_TYPES);
+	}
+	
+	/**
+	 * Adapts the behavior of the contained components to the change
+	 * encoded in the given event.
+	 *
+	 * @param event the event to which to adapt
+	 * @since 2.0
+	 */
+	private void adaptToPreferenceChange(PropertyChangeEvent event) {
+		if (fCodeScanner.affectsBehavior(event))
+			fCodeScanner.adaptToPreferenceChange(event);
+		if (fMultilineCommentScanner.affectsBehavior(event))
+			fMultilineCommentScanner.adaptToPreferenceChange(event);
+		if (fSinglelineCommentScanner.affectsBehavior(event))
+			fSinglelineCommentScanner.adaptToPreferenceChange(event);
+		if (fStringScanner.affectsBehavior(event))
+			fStringScanner.adaptToPreferenceChange(event);
+		if (fJavaDocScanner.affectsBehavior(event))
+			fJavaDocScanner.adaptToPreferenceChange(event);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWhitespaceDetector.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWhitespaceDetector.java
new file mode 100644
index 0000000..a14a2c1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWhitespaceDetector.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+/**
+ * A java aware white space detector.
+ */
+public class JavaWhitespaceDetector implements IWhitespaceDetector {
+
+	/**
+	 * @see IWhitespaceDetector#isWhitespace
+	 */
+	public boolean isWhitespace(char c) {
+		return Character.isWhitespace(c);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWordDetector.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWordDetector.java
new file mode 100644
index 0000000..8d46705
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWordDetector.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A Java aware word detector.
+ */
+public class JavaWordDetector implements IWordDetector {
+
+	/*
+	 * @see IWordDetector#isWordStart
+	 */
+	public boolean isWordStart(char c) {
+		return Character.isJavaIdentifierStart(c);
+	}
+
+	/*
+	 * @see IWordDetector#isWordPart
+	 */
+	public boolean isWordPart(char c) {
+		return Character.isJavaIdentifierPart(c);
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/PreferenceConstants.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/PreferenceConstants.java
new file mode 100644
index 0000000..502568e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/PreferenceConstants.java
@@ -0,0 +1,92 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+public class PreferenceConstants {
+	/**
+	 * Preference key suffix for bold text style preference keys.
+	 *
+	 * @since 2.1
+	 */
+	public static final String EDITOR_BOLD_SUFFIX= "_bold"; //$NON-NLS-1$
+	
+	/**
+	 * Preference key suffix for italic text style preference keys.
+	 *
+	 * @since 3.0
+	 */
+	public static final String EDITOR_ITALIC_SUFFIX= "_italic"; //$NON-NLS-1$
+
+	/**
+	 * Preference key suffix for strikethrough text style preference keys.
+	 *
+	 * @since 3.1
+	 */
+	public static final String EDITOR_STRIKETHROUGH_SUFFIX= "_strikethrough"; //$NON-NLS-1$
+
+	/**
+	 * Preference key suffix for underline text style preference keys.
+	 *
+	 * @since 3.1
+	 */
+	public static final String EDITOR_UNDERLINE_SUFFIX= "_underline"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference prefix for semantic highlighting preferences.
+	 *
+	 * @since 3.0
+	 */
+	public static final String EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX="semanticHighlighting."; //$NON-NLS-1$
+
+	/**
+	 * A named preference suffix that controls a semantic highlighting's color.
+	 * <p>
+	 * Value is of type <code>String</code>. A RGB color value encoded as a string
+	 * using class <code>PreferenceConverter</code>
+	 * </p>
+	 *
+	 * @see org.eclipse.jface.resource.StringConverter
+	 * @see org.eclipse.jface.preference.PreferenceConverter
+	 * @since 3.0
+	 */
+	public static final String EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX=".color"; //$NON-NLS-1$
+	
+	/**
+	 * A named preference suffix that controls if semantic highlighting has the text attribute bold.
+	 * <p>
+	 * Value is of type <code>Boolean</code>: <code>true</code> if bold.
+	 * </p>
+	 *
+	 * @since 3.0
+	 */
+	public static final String EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX=".bold"; //$NON-NLS-1$
+
+	/**
+	 * A named preference suffix that controls if semantic highlighting has the text attribute italic.
+	 * <p>
+	 * Value is of type <code>Boolean</code>: <code>true</code> if italic.
+	 * </p>
+	 *
+	 * @since 3.0
+	 */
+	public static final String EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX=".italic"; //$NON-NLS-1$
+
+	/**
+	 * A named preference suffix that controls if semantic highlighting has the text attribute strikethrough.
+	 * <p>
+	 * Value is of type <code>Boolean</code>: <code>true</code> if strikethrough.
+	 * </p>
+	 *
+	 * @since 3.1
+	 */
+	public static final String EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX=".strikethrough"; //$NON-NLS-1$
+
+	/**
+	 * A named preference suffix that controls if semantic highlighting has the text attribute underline.
+	 * <p>
+	 * Value is of type <code>Boolean</code>: <code>true</code> if underline.
+	 * </p>
+	 *
+	 * @since 3.1
+	 */
+	public static final String EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX=".underline"; //$NON-NLS-1$
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SemanticHighlightings.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SemanticHighlightings.java
new file mode 100644
index 0000000..bc51f61
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SemanticHighlightings.java
@@ -0,0 +1,10 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+public class SemanticHighlightings {
+	/**
+	 * A named preference part that controls the highlighting of annotations.
+	 *
+	 * @since 3.2
+	 */
+	public static final String ANNOTATION="annotation"; //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SingleTokenJavaScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SingleTokenJavaScanner.java
new file mode 100644
index 0000000..6df6041
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SingleTokenJavaScanner.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.List;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.IRule;
+
+
+/**
+ *
+ */
+public final class SingleTokenJavaScanner extends AbstractJavaScanner{
+
+
+	private String[] fProperty;
+
+	public SingleTokenJavaScanner(IColorManager manager, IPreferenceStore store, String property) {
+		super(manager, store);
+		fProperty= new String[] { property };
+		initialize();
+	}
+
+	/*
+	 * @see AbstractJavaScanner#getTokenProperties()
+	 */
+	protected String[] getTokenProperties() {
+		return fProperty;
+	}
+
+	/*
+	 * @see AbstractJavaScanner#createRules()
+	 */
+	protected List<IRule> createRules() {
+		setDefaultReturnToken(getToken(fProperty[0]));
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/AppearanceAwareLabelProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/AppearanceAwareLabelProvider.java
new file mode 100644
index 0000000..4931a54
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/AppearanceAwareLabelProvider.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Guven Demir <guven.internet+eclipse@gmail.com> - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+
+public class AppearanceAwareLabelProvider extends JavaUILabelProvider {
+	public final static long DEFAULT_TEXTFLAGS = JavaElementLabels.ROOT_VARIABLE
+			| JavaElementLabels.T_TYPE_PARAMETERS
+			| JavaElementLabels.M_PARAMETER_TYPES
+			| JavaElementLabels.M_APP_TYPE_PARAMETERS
+			| JavaElementLabels.M_APP_RETURNTYPE
+			| JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED;
+	public final static int DEFAULT_IMAGEFLAGS= JavaElementImageProvider.OVERLAY_ICONS;
+	
+//	private long fTextFlagMask;
+	
+	public AppearanceAwareLabelProvider(long textFlags, int imageFlags, Logger logger,
+			JavaUIMessages messages) {
+		super(textFlags, imageFlags, logger, messages);
+//		initMasks();
+	}
+
+	/**
+	 * Creates a labelProvider with DEFAULT_TEXTFLAGS and DEFAULT_IMAGEFLAGS
+	 */
+	public AppearanceAwareLabelProvider(Logger logger, JavaUIMessages messages) {
+		this(DEFAULT_TEXTFLAGS, DEFAULT_IMAGEFLAGS, logger, messages);
+	}
+	
+//	private void initMasks() {
+//		IPreferenceStore store= PreferenceConstants.getPreferenceStore();
+//		fTextFlagMask= -1;
+//		if (!store.getBoolean(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE)) {
+//			fTextFlagMask ^= JavaElementLabels.M_APP_RETURNTYPE;
+//		}
+//		if (!store.getBoolean(PreferenceConstants.APPEARANCE_METHOD_TYPEPARAMETERS)) {
+//			fTextFlagMask ^= JavaElementLabels.M_APP_TYPE_PARAMETERS;
+//		}
+//		if (!(store.getBoolean(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)
+//				|| store.getBoolean(JavaElementLabelComposer.APPEARANCE_ABBREVIATE_PACKAGE_NAMES))) {
+//			fTextFlagMask ^= JavaElementLabels.P_COMPRESSED;
+//		}
+//		if (!store.getBoolean(PreferenceConstants.APPEARANCE_CATEGORY)) {
+//			fTextFlagMask ^= JavaElementLabels.ALL_CATEGORY;
+//		}
+//
+//		fImageFlagMask= -1;
+//	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/ImageDescriptorRegistry.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/ImageDescriptorRegistry.java
new file mode 100644
index 0000000..22db248
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/ImageDescriptorRegistry.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A registry that maps <code>ImageDescriptors</code> to <code>Image</code>.
+ */
+public class ImageDescriptorRegistry {
+
+	private HashMap<ImageDescriptor,Image> fRegistry= new HashMap<ImageDescriptor,Image>(10);
+	private Display fDisplay;
+
+	/**
+	 * Creates a new image descriptor registry for the current or default display,
+	 * respectively.
+	 */
+	public ImageDescriptorRegistry() {
+		this(Display.getCurrent());
+	}
+
+	/**
+	 * Creates a new image descriptor registry for the given display. All images
+	 * managed by this registry will be disposed when the display gets disposed.
+	 *
+	 * @param display the display the images managed by this registry are allocated for
+	 */
+	public ImageDescriptorRegistry(Display display) {
+		fDisplay= display;
+		Assert.isNotNull(fDisplay);
+		hookDisplay();
+	}
+
+	/**
+	 * Returns the image associated with the given image descriptor.
+	 *
+	 * @param descriptor the image descriptor for which the registry manages an image,
+	 *  or <code>null</code> for a missing image descriptor
+	 * @return the image associated with the image descriptor or <code>null</code>
+	 *  if the image descriptor can't create the requested image.
+	 */
+	public Image get(ImageDescriptor descriptor) {
+		if (descriptor == null)
+			descriptor= ImageDescriptor.getMissingImageDescriptor();
+
+		Image result= (Image)fRegistry.get(descriptor);
+		if (result != null)
+			return result;
+
+		Assert.isTrue(fDisplay == Display.getCurrent(), "Allocating image for wrong display."); //$NON-NLS-1$
+		result= descriptor.createImage();
+		if (result != null)
+			fRegistry.put(descriptor, result);
+		return result;
+	}
+
+	/**
+	 * Disposes all images managed by this registry.
+	 */
+	public void dispose() {
+		for (Iterator<Image> iter= fRegistry.values().iterator(); iter.hasNext(); ) {
+			Image image= (Image)iter.next();
+			image.dispose();
+		}
+		fRegistry.clear();
+	}
+
+	private void hookDisplay() {
+		fDisplay.disposeExec(new Runnable() {
+			public void run() {
+				dispose();
+			}
+		});
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageDescriptor.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageDescriptor.java
new file mode 100644
index 0000000..95a2cfd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageDescriptor.java
@@ -0,0 +1,274 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+public class JavaElementImageDescriptor extends CompositeImageDescriptor {
+	/** Flag to render the abstract adornment. */
+	public final static int ABSTRACT= 		0x001;
+
+	/** Flag to render the final adornment. */
+	public final static int FINAL=			0x002;
+
+	/** Flag to render the synchronized adornment. */
+	public final static int SYNCHRONIZED=	0x004;
+
+	/** Flag to render the static adornment. */
+	public final static int STATIC=			0x008;
+
+	/** Flag to render the runnable adornment. */
+	public final static int RUNNABLE= 		0x010;
+
+	/** Flag to render the warning adornment. */
+	public final static int WARNING=			0x020;
+
+	/** Flag to render the error adornment. */
+	public final static int ERROR=			0x040;
+
+	/** Flag to render the 'override' adornment. */
+	public final static int OVERRIDES= 		0x080;
+
+	/** Flag to render the 'implements' adornment. */
+	public final static int IMPLEMENTS= 		0x100;
+
+	/** Flag to render the 'constructor' adornment. */
+	public final static int CONSTRUCTOR= 	0x200;
+
+	/**
+	 * Flag to render the 'deprecated' adornment.
+	 * @since 3.0
+	 */
+	public final static int DEPRECATED= 	0x400;
+
+	/**
+	 * Flag to render the 'volatile' adornment.
+	 * @since 3.3
+	 */
+	public final static int VOLATILE= 	0x800;
+
+	/**
+	 * Flag to render the 'transient' adornment.
+	 * @since 3.3
+	 */
+	public final static int TRANSIENT= 	0x1000;
+
+	private ImageDescriptor fBaseImage;
+	private int fFlags;
+	private Point fSize;
+	private Logger logger;
+	
+	/**
+	 * Creates a new JavaElementImageDescriptor.
+	 *
+	 * @param baseImage an image descriptor used as the base image
+	 * @param flags flags indicating which adornments are to be rendered. See {@link #setAdornments(int)}
+	 * 	for valid values.
+	 * @param size the size of the resulting image
+	 */
+	public JavaElementImageDescriptor(ImageDescriptor baseImage, int flags, Point size, Logger logger) {
+		this.logger = logger;
+		fBaseImage= baseImage;
+		Assert.isNotNull(fBaseImage);
+		fFlags= flags;
+		Assert.isTrue(fFlags >= 0);
+		fSize= size;
+		Assert.isNotNull(fSize);
+	}
+
+	/**
+	 * Sets the descriptors adornments. Valid values are: {@link #ABSTRACT}, {@link #FINAL},
+	 * {@link #SYNCHRONIZED}, {@link #STATIC}, {@link #RUNNABLE}, {@link #WARNING},
+	 * {@link #ERROR}, {@link #OVERRIDES}, {@link #IMPLEMENTS}, {@link #CONSTRUCTOR},
+	 * {@link #DEPRECATED}, {@link #VOLATILE}, {@link #TRANSIENT} or any combination of those.
+	 *
+	 * @param adornments the image descriptors adornments
+	 */
+	public void setAdornments(int adornments) {
+		Assert.isTrue(adornments >= 0);
+		fFlags= adornments;
+	}
+
+	/**
+	 * Returns the current adornments.
+	 *
+	 * @return the current adornments
+	 */
+	public int getAdronments() {
+		return fFlags;
+	}
+
+	/**
+	 * Sets the size of the image created by calling {@link #createImage()}.
+	 *
+	 * @param size the size of the image returned from calling {@link #createImage()}
+	 */
+	public void setImageSize(Point size) {
+		Assert.isNotNull(size);
+		Assert.isTrue(size.x >= 0 && size.y >= 0);
+		fSize= size;
+	}
+
+	/**
+	 * Returns the size of the image created by calling {@link #createImage()}.
+	 *
+	 * @return the size of the image created by calling {@link #createImage()}
+	 */
+	public Point getImageSize() {
+		return new Point(fSize.x, fSize.y);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared in CompositeImageDescriptor
+	 */
+	protected Point getSize() {
+		return fSize;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Object.
+	 */
+	public boolean equals(Object object) {
+		if (object == null || !JavaElementImageDescriptor.class.equals(object.getClass()))
+			return false;
+
+		JavaElementImageDescriptor other= (JavaElementImageDescriptor)object;
+		return (fBaseImage.equals(other.fBaseImage) && fFlags == other.fFlags && fSize.equals(other.fSize));
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Object.
+	 */
+	public int hashCode() {
+		return fBaseImage.hashCode() | fFlags | fSize.hashCode();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared in CompositeImageDescriptor
+	 */
+	protected void drawCompositeImage(int width, int height) {
+		ImageData bg= getImageData(fBaseImage);
+
+		if ((fFlags & DEPRECATED) != 0) { // draw *behind* the full image
+			Point size= getSize();
+			ImageData data= getImageData(JavaPluginImages.DESC_OVR_DEPRECATED);
+			drawImage(data, 0, size.y - data.height);
+		}
+		drawImage(bg, 0, 0);
+
+		drawTopRight();
+		drawBottomRight();
+		drawBottomLeft();
+
+
+	}
+
+	private ImageData getImageData(ImageDescriptor descriptor) {
+		ImageData data= descriptor.getImageData(); // see bug 51965: getImageData can return null
+		if (data == null) {
+			data= DEFAULT_IMAGE_DATA;
+			logger.error("Image data not available: " + descriptor.toString());
+		}
+		return data;
+	}
+
+	private void addTopRightImage(ImageDescriptor desc, Point pos) {
+		ImageData data= getImageData(desc);
+		int x= pos.x - data.width;
+		if (x >= 0) {
+			drawImage(data, x, pos.y);
+			pos.x= x;
+		}
+	}
+
+	private void addBottomRightImage(ImageDescriptor desc, Point pos) {
+		ImageData data= getImageData(desc);
+		int x= pos.x - data.width;
+		int y= pos.y - data.height;
+		if (x >= 0 && y >= 0) {
+			drawImage(data, x, y);
+			pos.x= x;
+		}
+	}
+
+	private void addBottomLeftImage(ImageDescriptor desc, Point pos) {
+		ImageData data= getImageData(desc);
+		int x= pos.x;
+		int y= pos.y - data.height;
+		if (x + data.width < getSize().x && y >= 0) {
+			drawImage(data, x, y);
+			pos.x= x + data.width;
+		}
+	}
+
+
+	private void drawTopRight() {
+		Point pos= new Point(getSize().x, 0);
+		if ((fFlags & ABSTRACT) != 0) {
+			addTopRightImage(JavaPluginImages.DESC_OVR_ABSTRACT, pos);
+		}
+		if ((fFlags & CONSTRUCTOR) != 0) {
+			addTopRightImage(JavaPluginImages.DESC_OVR_CONSTRUCTOR, pos);
+		}
+		if ((fFlags & FINAL) != 0) {
+			addTopRightImage(JavaPluginImages.DESC_OVR_FINAL, pos);
+		}
+		if ((fFlags & VOLATILE) != 0) {
+			addTopRightImage(JavaPluginImages.DESC_OVR_VOLATILE, pos);
+		}
+		if ((fFlags & STATIC) != 0) {
+			addTopRightImage(JavaPluginImages.DESC_OVR_STATIC, pos);
+		}
+
+	}
+
+	private void drawBottomRight() {
+		Point size= getSize();
+		Point pos= new Point(size.x, size.y);
+
+		int flags= fFlags;
+
+		int syncAndOver= SYNCHRONIZED | OVERRIDES;
+		int syncAndImpl= SYNCHRONIZED | IMPLEMENTS;
+
+		if ((flags & syncAndOver) == syncAndOver) { // both flags set: merged overlay image
+			addBottomRightImage(JavaPluginImages.DESC_OVR_SYNCH_AND_OVERRIDES, pos);
+			flags &= ~syncAndOver; // clear to not render again
+		} else if ((flags & syncAndImpl) == syncAndImpl) { // both flags set: merged overlay image
+			addBottomRightImage(JavaPluginImages.DESC_OVR_SYNCH_AND_IMPLEMENTS, pos);
+			flags &= ~syncAndImpl; // clear to not render again
+		}
+		if ((flags & OVERRIDES) != 0) {
+			addBottomRightImage(JavaPluginImages.DESC_OVR_OVERRIDES, pos);
+		}
+		if ((flags & IMPLEMENTS) != 0) {
+			addBottomRightImage(JavaPluginImages.DESC_OVR_IMPLEMENTS, pos);
+		}
+		if ((flags & SYNCHRONIZED) != 0) {
+			addBottomRightImage(JavaPluginImages.DESC_OVR_SYNCH, pos);
+		}
+		if ((flags & RUNNABLE) != 0) {
+			addBottomRightImage(JavaPluginImages.DESC_OVR_RUN, pos);
+		}
+		if ((flags & TRANSIENT) != 0) {
+			addBottomRightImage(JavaPluginImages.DESC_OVR_TRANSIENT, pos);
+		}
+	}
+
+	private void drawBottomLeft() {
+		Point pos= new Point(0, getSize().y);
+		if ((fFlags & ERROR) != 0) {
+			addBottomLeftImage(JavaPluginImages.DESC_OVR_ERROR, pos);
+		}
+//FIXME		if ((fFlags & PackageExplorerProblemsDecorator.BUILDPATH_ERROR) != 0) {
+//			addBottomLeftImage(JavaPluginImages.DESC_OVR_BUILDPATH_ERROR, pos);
+//		}
+		if ((fFlags & WARNING) != 0) {
+			addBottomLeftImage(JavaPluginImages.DESC_OVR_WARNING, pos);
+		}
+
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageProvider.java
new file mode 100644
index 0000000..dc86e34
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageProvider.java
@@ -0,0 +1,482 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+public class JavaElementImageProvider {
+	private Logger logger;
+	
+	/**
+	 * Flags for the JavaImageLabelProvider:
+	 * Generate images with overlays.
+	 */
+	public final static int OVERLAY_ICONS= 0x1;
+
+	/**
+	 * Generate small sized images.
+	 */
+	public final static int SMALL_ICONS= 0x2;
+	
+	/**
+	 * Use the 'light' style for rendering types.
+	 */
+	public final static int LIGHT_TYPE_ICONS= 0x4;
+	
+	public static final Point SMALL_SIZE= new Point(16, 16);
+	public static final Point BIG_SIZE= new Point(22, 16);
+	
+//	private static ImageDescriptor DESC_OBJ_PROJECT_CLOSED;
+//	private static ImageDescriptor DESC_OBJ_PROJECT;
+//	{
+//		SharedImageKeys images = JavaPlugin.getDefault().getWorkbench().getSharedImages();
+//		DESC_OBJ_PROJECT_CLOSED= images.getImageDescriptor(IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED);
+//		DESC_OBJ_PROJECT= 		 images.getImageDescriptor(IDE.SharedImages.IMG_OBJ_PROJECT);
+//	}
+
+	private ImageDescriptorRegistry fRegistry;
+
+	public JavaElementImageProvider(Logger logger) {
+		this.logger = logger;
+	}
+	
+	/**
+	 * Returns the icon for a given element. The icon depends on the element type
+	 * and element properties. If configured, overlay icons are constructed for
+	 * <code>ISourceReference</code>s.
+	 * @param element the element
+	 * @param flags Flags as defined by the JavaImageLabelProvider
+	 * @return return the image or <code>null</code>
+	 */
+	public Image getImageLabel(Object element, int flags, Logger logger) {
+		return getImageLabel(computeDescriptor(element, flags,logger));
+	}
+	
+	private Image getImageLabel(ImageDescriptor descriptor){
+		if (descriptor == null)
+			return null;
+		return getRegistry().get(descriptor);
+	}
+	
+	private ImageDescriptorRegistry getRegistry() {
+		if (fRegistry == null) {
+			fRegistry= JavaPluginImages.IMAGE_DESCRIPTOR_REGISTRY;
+		}
+		return fRegistry;
+	}
+
+	
+	private ImageDescriptor computeDescriptor(Object element, int flags, Logger logger){
+		if (element instanceof IJavaElement) {
+			return getJavaImageDescriptor((IJavaElement) element, flags, logger);
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns an image descriptor for a java element. The descriptor includes overlays, if specified.
+	 * @param element the Java element
+	 * @param flags the image flags
+	 * @return returns the image descriptor
+	 */
+	public ImageDescriptor getJavaImageDescriptor(IJavaElement element, int flags, Logger logger) {
+		Point size= useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
+
+		ImageDescriptor baseDesc= getBaseImageDescriptor(element, flags);
+		if (baseDesc != null) {
+			int adornmentFlags= computeJavaAdornmentFlags(element, flags);
+			return new JavaElementImageDescriptor(baseDesc, adornmentFlags, size, logger);
+		}
+		return new JavaElementImageDescriptor(JavaPluginImages.DESC_OBJS_GHOST, 0, size, logger);
+	}
+	
+	/**
+	 * Returns an image descriptor for a java element. This is the base image, no overlays.
+	 * @param element the element
+	 * @param renderFlags the image flags
+	 * @return returns the image descriptor
+	 */
+	public ImageDescriptor getBaseImageDescriptor(IJavaElement element, int renderFlags) {
+
+		try {
+			switch (element.getElementType()) {
+				case IJavaElement.INITIALIZER:
+					return JavaPluginImages.DESC_MISC_PRIVATE; // 23479
+				case IJavaElement.METHOD: {
+					IMethod method= (IMethod) element;
+					IType declType= method.getDeclaringType();
+					int flags= method.getFlags();
+					if (declType.isEnum() && isDefaultFlag(flags) && method.isConstructor())
+						return JavaPluginImages.DESC_MISC_PRIVATE;
+					return getMethodImageDescriptor(JavaModelUtil.isInterfaceOrAnnotation(declType), flags);
+				}
+				case IJavaElement.FIELD: {
+					IMember member= (IMember) element;
+					IType declType= member.getDeclaringType();
+					return getFieldImageDescriptor(JavaModelUtil.isInterfaceOrAnnotation(declType), member.getFlags());
+				}
+				case IJavaElement.LOCAL_VARIABLE:
+					return JavaPluginImages.DESC_OBJS_LOCAL_VARIABLE;
+
+				case IJavaElement.PACKAGE_DECLARATION:
+					return JavaPluginImages.DESC_OBJS_PACKDECL;
+
+				case IJavaElement.IMPORT_DECLARATION:
+					return JavaPluginImages.DESC_OBJS_IMPDECL;
+
+				case IJavaElement.IMPORT_CONTAINER:
+					return JavaPluginImages.DESC_OBJS_IMPCONT;
+
+				case IJavaElement.TYPE: {
+					IType type= (IType) element;
+
+					IType declType= type.getDeclaringType();
+					boolean isInner= declType != null;
+					boolean isInInterfaceOrAnnotation= isInner && JavaModelUtil.isInterfaceOrAnnotation(declType);
+					return getTypeImageDescriptor(isInner, isInInterfaceOrAnnotation, type.getFlags(), useLightIcons(renderFlags));
+				}
+
+				case IJavaElement.PACKAGE_FRAGMENT_ROOT: {
+					IPackageFragmentRoot root= (IPackageFragmentRoot) element;
+					IPath attach= root.getSourceAttachmentPath();
+					if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
+						if (root.isArchive()) {
+							if (root.isExternal()) {
+								if (attach == null) {
+									return JavaPluginImages.DESC_OBJS_EXTJAR;
+								} else {
+									return JavaPluginImages.DESC_OBJS_EXTJAR_WSRC;
+								}
+							} else {
+								if (attach == null) {
+									return JavaPluginImages.DESC_OBJS_JAR;
+								} else {
+									return JavaPluginImages.DESC_OBJS_JAR_WSRC;
+								}
+							}
+						} else {
+							if (attach == null) {
+								return JavaPluginImages.DESC_OBJS_CLASSFOLDER;
+							} else {
+								return JavaPluginImages.DESC_OBJS_CLASSFOLDER_WSRC;
+							}
+						}
+					} else {
+						return JavaPluginImages.DESC_OBJS_PACKFRAG_ROOT;
+					}
+				}
+
+				case IJavaElement.PACKAGE_FRAGMENT:
+					return getPackageFragmentIcon(element);
+
+
+				case IJavaElement.COMPILATION_UNIT:
+					return JavaPluginImages.DESC_OBJS_CUNIT;
+
+				case IJavaElement.CLASS_FILE:
+					/* this is too expensive for large packages
+					try {
+						IClassFile cfile= (IClassFile)element;
+						if (cfile.isClass())
+							return JavaPluginImages.IMG_OBJS_CFILECLASS;
+						return JavaPluginImages.IMG_OBJS_CFILEINT;
+					} catch(JavaModelException e) {
+						// fall through;
+					}*/
+					return JavaPluginImages.DESC_OBJS_CFILE;
+
+				case IJavaElement.JAVA_PROJECT:
+					IJavaProject jp= (IJavaProject)element;
+					if (jp.getProject().isOpen()) {
+//FIXME						IProject project= jp.getProject();
+//						IWorkbenchAdapter adapter= (IWorkbenchAdapter)project.getAdapter(IWorkbenchAdapter.class);
+//						if (adapter != null) {
+//							ImageDescriptor result= adapter.getImageDescriptor(project);
+//							if (result != null)
+//								return result;
+//						}
+						return JavaPluginImages.DESC_OBJ_PROJECT;
+					}
+					return JavaPluginImages.DESC_OBJ_PROJECT_CLOSED;
+				case IJavaElement.JAVA_MODEL:
+					return JavaPluginImages.DESC_OBJS_JAVA_MODEL;
+
+				case IJavaElement.TYPE_PARAMETER:
+					return JavaPluginImages.DESC_OBJS_TYPEVARIABLE;
+
+				case IJavaElement.ANNOTATION:
+					return JavaPluginImages.DESC_OBJS_ANNOTATION;
+
+				default:
+					// ignore. Must be a new, yet unknown Java element
+					// give an advanced IWorkbenchAdapter the chance
+//FIXME					IWorkbenchAdapter wbAdapter= (IWorkbenchAdapter) element.getAdapter(IWorkbenchAdapter.class);
+//					if (wbAdapter != null && !(wbAdapter instanceof JavaWorkbenchAdapter)) { // avoid recursion
+//						ImageDescriptor imageDescriptor= wbAdapter.getImageDescriptor(element);
+//						if (imageDescriptor != null) {
+//							return imageDescriptor;
+//						}
+//					}
+					return JavaPluginImages.DESC_OBJS_GHOST;
+			}
+
+		} catch (JavaModelException e) {
+			if (e.isDoesNotExist())
+				return JavaPluginImages.DESC_OBJS_UNKNOWN;
+			logger.error(e);
+			return JavaPluginImages.DESC_OBJS_GHOST;
+		}
+	}
+	
+	public static ImageDescriptor getMethodImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+		if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+			return JavaPluginImages.DESC_MISC_PUBLIC;
+		if (Flags.isProtected(flags))
+			return JavaPluginImages.DESC_MISC_PROTECTED;
+		if (Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_MISC_PRIVATE;
+
+		return JavaPluginImages.DESC_MISC_DEFAULT;
+	}
+
+	public static ImageDescriptor getFieldImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+		if (Flags.isPublic(flags) || isInInterfaceOrAnnotation || Flags.isEnum(flags))
+			return JavaPluginImages.DESC_FIELD_PUBLIC;
+		if (Flags.isProtected(flags))
+			return JavaPluginImages.DESC_FIELD_PROTECTED;
+		if (Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_FIELD_PRIVATE;
+
+		return JavaPluginImages.DESC_FIELD_DEFAULT;
+	}
+	
+	private static boolean isDefaultFlag(int flags) {
+		return !Flags.isPublic(flags) && !Flags.isProtected(flags) && !Flags.isPrivate(flags);
+	}
+	
+	private static boolean useSmallSize(int flags) {
+		return (flags & SMALL_ICONS) != 0;
+	}
+	
+	private ImageDescriptor getPackageFragmentIcon(IJavaElement element) throws JavaModelException {
+		IPackageFragment fragment= (IPackageFragment)element;
+		boolean containsJavaElements= false;
+		try {
+			containsJavaElements= fragment.hasChildren();
+		} catch(JavaModelException e) {
+			// assuming no children;
+		}
+		if(!containsJavaElements && (fragment.getNonJavaResources().length > 0))
+			return JavaPluginImages.DESC_OBJS_EMPTY_PACKAGE_RESOURCES;
+		else if (!containsJavaElements)
+			return JavaPluginImages.DESC_OBJS_EMPTY_PACKAGE;
+		return JavaPluginImages.DESC_OBJS_PACKAGE;
+	}
+	
+	private static boolean useLightIcons(int flags) {
+		return (flags & LIGHT_TYPE_ICONS) != 0;
+	}
+	
+	public static ImageDescriptor getTypeImageDescriptor(boolean isInner, boolean isInInterfaceOrAnnotation, int flags, boolean useLightIcons) {
+		if (Flags.isEnum(flags)) {
+			if (useLightIcons) {
+				return JavaPluginImages.DESC_OBJS_ENUM_ALT;
+			}
+			if (isInner) {
+				return getInnerEnumImageDescriptor(isInInterfaceOrAnnotation, flags);
+			}
+			return getEnumImageDescriptor(flags);
+		} else if (Flags.isAnnotation(flags)) {
+			if (useLightIcons) {
+				return JavaPluginImages.DESC_OBJS_ANNOTATION_ALT;
+			}
+			if (isInner) {
+				return getInnerAnnotationImageDescriptor(isInInterfaceOrAnnotation, flags);
+			}
+			return getAnnotationImageDescriptor(flags);
+		}  else if (Flags.isInterface(flags)) {
+			if (useLightIcons) {
+				return JavaPluginImages.DESC_OBJS_INTERFACEALT;
+			}
+			if (isInner) {
+				return getInnerInterfaceImageDescriptor(isInInterfaceOrAnnotation, flags);
+			}
+			return getInterfaceImageDescriptor(flags);
+		} else {
+			if (useLightIcons) {
+				return JavaPluginImages.DESC_OBJS_CLASSALT;
+			}
+			if (isInner) {
+				return getInnerClassImageDescriptor(isInInterfaceOrAnnotation, flags);
+			}
+			return getClassImageDescriptor(flags);
+		}
+	}
+	
+	private static ImageDescriptor getInnerEnumImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+		if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+			return JavaPluginImages.DESC_OBJS_ENUM;
+		else if (Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_ENUM_PRIVATE;
+		else if (Flags.isProtected(flags))
+			return JavaPluginImages.DESC_OBJS_ENUM_PROTECTED;
+		else
+			return JavaPluginImages.DESC_OBJS_ENUM_DEFAULT;
+	}
+	
+	private static ImageDescriptor getEnumImageDescriptor(int flags) {
+		if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_ENUM;
+		else
+			return JavaPluginImages.DESC_OBJS_ENUM_DEFAULT;
+	}
+
+	private static ImageDescriptor getInnerAnnotationImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+		if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+			return JavaPluginImages.DESC_OBJS_ANNOTATION;
+		else if (Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_ANNOTATION_PRIVATE;
+		else if (Flags.isProtected(flags))
+			return JavaPluginImages.DESC_OBJS_ANNOTATION_PROTECTED;
+		else
+			return JavaPluginImages.DESC_OBJS_ANNOTATION_DEFAULT;
+	}
+
+	private static ImageDescriptor getAnnotationImageDescriptor(int flags) {
+		if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_ANNOTATION;
+		else
+			return JavaPluginImages.DESC_OBJS_ANNOTATION_DEFAULT;
+	}
+
+	private static ImageDescriptor getInnerInterfaceImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+		if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+			return JavaPluginImages.DESC_OBJS_INNER_INTERFACE_PUBLIC;
+		else if (Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_INNER_INTERFACE_PRIVATE;
+		else if (Flags.isProtected(flags))
+			return JavaPluginImages.DESC_OBJS_INNER_INTERFACE_PROTECTED;
+		else
+			return JavaPluginImages.DESC_OBJS_INTERFACE_DEFAULT;
+	}
+
+	private static ImageDescriptor getInterfaceImageDescriptor(int flags) {
+		if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_INTERFACE;
+		else
+			return JavaPluginImages.DESC_OBJS_INTERFACE_DEFAULT;
+	}
+
+	private static ImageDescriptor getInnerClassImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+		if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+			return JavaPluginImages.DESC_OBJS_INNER_CLASS_PUBLIC;
+		else if (Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_INNER_CLASS_PRIVATE;
+		else if (Flags.isProtected(flags))
+			return JavaPluginImages.DESC_OBJS_INNER_CLASS_PROTECTED;
+		else
+			return JavaPluginImages.DESC_OBJS_INNER_CLASS_DEFAULT;
+	}
+
+	private static ImageDescriptor getClassImageDescriptor(int flags) {
+		if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+			return JavaPluginImages.DESC_OBJS_CLASS;
+		else
+			return JavaPluginImages.DESC_OBJS_CLASS_DEFAULT;
+	}
+
+	private static boolean showOverlayIcons(int flags) {
+		return (flags & OVERLAY_ICONS) != 0;
+	}
+	
+	private int computeJavaAdornmentFlags(IJavaElement element, int renderFlags) {
+		int flags= 0;
+		if (showOverlayIcons(renderFlags) && element instanceof IMember) {
+			try {
+				IMember member= (IMember) element;
+
+				if (element.getElementType() == IJavaElement.METHOD && ((IMethod)element).isConstructor())
+					flags |= JavaElementImageDescriptor.CONSTRUCTOR;
+
+				int modifiers= member.getFlags();
+				if (Flags.isAbstract(modifiers) && confirmAbstract(member))
+					flags |= JavaElementImageDescriptor.ABSTRACT;
+				if (Flags.isFinal(modifiers) || isInterfaceOrAnnotationField(member) || isEnumConstant(member, modifiers))
+					flags |= JavaElementImageDescriptor.FINAL;
+				if (Flags.isSynchronized(modifiers) && confirmSynchronized(member))
+					flags |= JavaElementImageDescriptor.SYNCHRONIZED;
+				if (Flags.isStatic(modifiers) || isInterfaceOrAnnotationFieldOrType(member) || isEnumConstant(member, modifiers))
+					flags |= JavaElementImageDescriptor.STATIC;
+
+				if (Flags.isDeprecated(modifiers))
+					flags |= JavaElementImageDescriptor.DEPRECATED;
+				if (member.getElementType() == IJavaElement.TYPE) {
+					if (JavaModelUtil.hasMainMethod((IType) member)) {
+						flags |= JavaElementImageDescriptor.RUNNABLE;
+					}
+				}
+				if (member.getElementType() == IJavaElement.FIELD) {
+					if (Flags.isVolatile(modifiers))
+						flags |= JavaElementImageDescriptor.VOLATILE;
+					if (Flags.isTransient(modifiers))
+						flags |= JavaElementImageDescriptor.TRANSIENT;
+				}
+
+
+			} catch (JavaModelException e) {
+				// do nothing. Can't compute runnable adornment or get flags
+			}
+		}
+		return flags;
+	}
+	
+	private static boolean confirmAbstract(IMember element) throws JavaModelException {
+		// never show the abstract symbol on interfaces or members in interfaces
+		if (element.getElementType() == IJavaElement.TYPE) {
+			return ! JavaModelUtil.isInterfaceOrAnnotation((IType) element);
+		}
+		return ! JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+	}
+
+	private static boolean isInterfaceOrAnnotationField(IMember element) throws JavaModelException {
+		// always show the final symbol on interface fields
+		if (element.getElementType() == IJavaElement.FIELD) {
+			return JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+		}
+		return false;
+	}
+
+	private static boolean confirmSynchronized(IJavaElement member) {
+		// Synchronized types are allowed but meaningless.
+		return member.getElementType() != IJavaElement.TYPE;
+	}
+
+	private static boolean isEnumConstant(IMember element, int modifiers) {
+		if (element.getElementType() == IJavaElement.FIELD) {
+			return Flags.isEnum(modifiers);
+		}
+		return false;
+	}
+
+	private static boolean isInterfaceOrAnnotationFieldOrType(IMember element) throws JavaModelException {
+		// always show the static symbol on interface fields and types
+		if (element.getElementType() == IJavaElement.FIELD) {
+			return JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+		} else if (element.getElementType() == IJavaElement.TYPE && element.getDeclaringType() != null) {
+			return JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+		}
+		return false;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabelComposer.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabelComposer.java
new file mode 100644
index 0000000..1ed4257
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabelComposer.java
@@ -0,0 +1,1487 @@
+/*******************************************************************************
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Guven Demir <guven.internet+eclipse@gmail.com> - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import java.util.jar.Attributes.Name;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.StyledString.Styler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.TextStyle;
+import org.eclipse.swt.widgets.Display;
+
+public class JavaElementLabelComposer {
+	/**
+	 * An adapter for buffer supported by the label composer.
+	 */
+	public static abstract class FlexibleBuffer {
+
+		/**
+		 * Appends the string representation of the given character to the
+		 * buffer.
+		 * 
+		 * @param ch
+		 *            the character to append
+		 * @return a reference to this object
+		 */
+		public abstract FlexibleBuffer append(char ch);
+
+		/**
+		 * Appends the given string to the buffer.
+		 * 
+		 * @param string
+		 *            the string to append
+		 * @return a reference to this object
+		 */
+		public abstract FlexibleBuffer append(String string);
+
+		/**
+		 * Returns the length of the the buffer.
+		 * 
+		 * @return the length of the current string
+		 */
+		public abstract int length();
+
+		/**
+		 * Sets a styler to use for the given source range. The range must be
+		 * subrange of actual string of this buffer. Stylers previously set for
+		 * that range will be overwritten.
+		 * 
+		 * @param offset
+		 *            the start offset of the range
+		 * @param length
+		 *            the length of the range
+		 * @param styler
+		 *            the styler to set
+		 * 
+		 * @throws StringIndexOutOfBoundsException
+		 *             if <code>start</code> is less than zero, or if offset
+		 *             plus length is greater than the length of this object.
+		 */
+		public abstract void setStyle(int offset, int length, Styler styler);
+	}
+
+	public static class FlexibleStringBuffer extends FlexibleBuffer {
+		private final StringBuffer fStringBuffer;
+
+		public FlexibleStringBuffer(StringBuffer stringBuffer) {
+			fStringBuffer = stringBuffer;
+		}
+
+		public FlexibleBuffer append(char ch) {
+			fStringBuffer.append(ch);
+			return this;
+		}
+
+		public FlexibleBuffer append(String string) {
+			fStringBuffer.append(string);
+			return this;
+		}
+
+		public int length() {
+			return fStringBuffer.length();
+		}
+
+		public void setStyle(int offset, int length, Styler styler) {
+			// no style
+		}
+
+		public String toString() {
+			return fStringBuffer.toString();
+		}
+	}
+
+	public static class FlexibleStyledString extends FlexibleBuffer {
+		private final StyledString fStyledString;
+
+		public FlexibleStyledString(StyledString stringBuffer) {
+			fStyledString = stringBuffer;
+		}
+
+		public FlexibleBuffer append(char ch) {
+			fStyledString.append(ch);
+			return this;
+		}
+
+		public FlexibleBuffer append(String string) {
+			fStyledString.append(string);
+			return this;
+		}
+
+		public int length() {
+			return fStyledString.length();
+		}
+
+		public void setStyle(int offset, int length, Styler styler) {
+			fStyledString.setStyle(offset, length, styler);
+		}
+
+		public String toString() {
+			return fStyledString.toString();
+		}
+	}
+
+//TODO FIXME	private static final Styler QUALIFIER_STYLE = StyledString.QUALIFIER_STYLER;
+	private static final Styler QUALIFIER_STYLE = new Styler() {
+		private Color COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
+		
+		@Override
+		public void applyStyles(TextStyle textStyle) {
+			textStyle.foreground = COLOR;
+		}
+	};
+	
+	private static final Styler COUNTER_STYLE = new Styler() {
+		private Color COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
+		
+		@Override
+		public void applyStyles(TextStyle textStyle) {
+			textStyle.foreground = COLOR;
+		}
+	};
+	private static final Styler DECORATIONS_STYLE = new Styler() {
+		private Color COLOR = new Color(Display.getCurrent(), new RGB(149, 125, 71));
+		
+		@Override
+		public void applyStyles(TextStyle textStyle) {
+			textStyle.foreground = COLOR;
+		}
+	};
+
+	private final static long QUALIFIER_FLAGS = JavaElementLabels.P_COMPRESSED
+			| JavaElementLabels.USE_RESOLVED;
+
+	private final FlexibleBuffer fBuffer;
+	private Logger logger;
+	private JavaUIMessages messages;
+
+	/**
+	 * Creates a new java element composer based on the given buffer.
+	 * 
+	 * @param buffer
+	 *            the buffer
+	 */
+	public JavaElementLabelComposer(StringBuffer buffer, Logger logger,
+			JavaUIMessages messages) {
+		this(new FlexibleStringBuffer(buffer), logger, messages);
+	}
+
+	/**
+	 * Creates a new java element composer based on the given buffer.
+	 * 
+	 * @param buffer
+	 *            the buffer
+	 */
+	public JavaElementLabelComposer(StyledString buffer, Logger logger,
+			JavaUIMessages messages) {
+		this(new FlexibleStyledString(buffer), logger, messages);
+	}
+
+	/**
+	 * Creates a new java element composer based on the given buffer.
+	 * 
+	 * @param buffer
+	 *            the buffer
+	 */
+	public JavaElementLabelComposer(FlexibleBuffer buffer, Logger logger,
+			JavaUIMessages messages) {
+		fBuffer = buffer;
+		this.logger = logger;
+		this.messages = messages;
+	}
+
+	private static final boolean getFlag(long flags, long flag) {
+		return (flags & flag) != 0;
+	}
+
+	/**
+	 * Appends the label for a package fragment root. Considers the ROOT_*
+	 * flags.
+	 * 
+	 * @param root
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with ROOT_' are
+	 *            considered.
+	 */
+	public void appendPackageFragmentRootLabel(IPackageFragmentRoot root,
+			long flags) {
+		// Handle variables different
+		if (getFlag(flags, JavaElementLabels.ROOT_VARIABLE)
+				&& appendVariableLabel(root, flags))
+			return;
+		if (root.isArchive())
+			appendArchiveLabel(root, flags);
+		else
+			appendFolderLabel(root, flags);
+	}
+
+	private void appendArchiveLabel(IPackageFragmentRoot root, long flags) {
+		boolean external = root.isExternal();
+		if (external)
+			appendExternalArchiveLabel(root, flags);
+		else
+			appendInternalArchiveLabel(root, flags);
+	}
+
+	private void appendExternalArchiveLabel(IPackageFragmentRoot root,
+			long flags) {
+		IPath path;
+		IClasspathEntry classpathEntry = null;
+		try {
+			classpathEntry = JavaModelUtil.getClasspathEntry(root);
+			IPath rawPath = classpathEntry.getPath();
+			if (classpathEntry.getEntryKind() != IClasspathEntry.CPE_CONTAINER
+					&& !rawPath.isAbsolute())
+				path = rawPath;
+			else
+				path = root.getPath();
+		} catch (JavaModelException e) {
+			path = root.getPath();
+		}
+		if (getFlag(flags, JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED)) {
+			int segements = path.segmentCount();
+			if (segements > 0) {
+				fBuffer.append(path.segment(segements - 1));
+				int offset = fBuffer.length();
+				if (segements > 1 || path.getDevice() != null) {
+					fBuffer.append(JavaElementLabels.CONCAT_STRING);
+					fBuffer.append(path.removeLastSegments(1).toOSString());
+				}
+				if (classpathEntry != null) {
+					IClasspathEntry referencingEntry = classpathEntry
+							.getReferencingEntry();
+					if (referencingEntry != null) {
+						fBuffer.append(messages
+								.JavaElementLabels_onClassPathOf(
+										Name.CLASS_PATH.toString(),
+										referencingEntry.getPath()
+												.lastSegment()));
+					}
+				}
+				if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+					fBuffer.setStyle(offset, fBuffer.length() - offset,
+							QUALIFIER_STYLE);
+				}
+			} else {
+				fBuffer.append(path.toOSString());
+			}
+		} else {
+			fBuffer.append(path.toOSString());
+		}
+	}
+
+	private void appendFolderLabel(IPackageFragmentRoot root, long flags) {
+		IResource resource = root.getResource();
+		if (resource == null) {
+			appendExternalArchiveLabel(root, flags);
+			return;
+		}
+
+		boolean rootQualified = getFlag(flags, JavaElementLabels.ROOT_QUALIFIED);
+		boolean referencedQualified = getFlag(flags,
+				JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED)
+				&& isReferenced(root);
+		if (rootQualified) {
+			fBuffer.append(root.getPath().makeRelative().toString());
+		} else {
+			IPath projectRelativePath = resource.getProjectRelativePath();
+			if (projectRelativePath.segmentCount() == 0) {
+				fBuffer.append(resource.getName());
+				referencedQualified = false;
+			} else {
+				fBuffer.append(projectRelativePath.toString());
+			}
+
+			int offset = fBuffer.length();
+			if (referencedQualified) {
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				fBuffer.append(resource.getProject().getName());
+			} else if (getFlag(flags, JavaElementLabels.ROOT_POST_QUALIFIED)) {
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				fBuffer.append(root.getParent().getElementName());
+			} else {
+				return;
+			}
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	private boolean appendVariableLabel(IPackageFragmentRoot root, long flags) {
+		try {
+			IClasspathEntry rawEntry = root.getRawClasspathEntry();
+			if (rawEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
+				IClasspathEntry entry = JavaModelUtil.getClasspathEntry(root);
+				if (entry.getReferencingEntry() != null) {
+					return false; // not the variable entry itself, but a
+									// referenced entry
+				}
+				IPath path = rawEntry.getPath().makeRelative();
+
+				if (getFlag(flags,
+						JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED)) {
+					int segements = path.segmentCount();
+					if (segements > 0) {
+						fBuffer.append(path.segment(segements - 1));
+						if (segements > 1) {
+							int offset = fBuffer.length();
+							fBuffer.append(JavaElementLabels.CONCAT_STRING);
+							fBuffer.append(path.removeLastSegments(1)
+									.toOSString());
+							if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+								fBuffer.setStyle(offset, fBuffer.length()
+										- offset, QUALIFIER_STYLE);
+							}
+						}
+					} else {
+						fBuffer.append(path.toString());
+					}
+				} else {
+					fBuffer.append(path.toString());
+				}
+				int offset = fBuffer.length();
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				if (root.isExternal())
+					fBuffer.append(root.getPath().toOSString());
+				else
+					fBuffer.append(root.getPath().makeRelative().toString());
+
+				if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+					fBuffer.setStyle(offset, fBuffer.length() - offset,
+							QUALIFIER_STYLE);
+				}
+				return true;
+			}
+		} catch (JavaModelException e) {
+			// problems with class path, ignore (bug 202792)
+			return false;
+		}
+		return false;
+	}
+
+	/**
+	 * Appends the label for a Java element with the flags as defined by this
+	 * class.
+	 * 
+	 * @param element
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags.
+	 */
+	public void appendElementLabel(IJavaElement element, long flags) {
+		int type = element.getElementType();
+		IPackageFragmentRoot root = null;
+
+		if (type != IJavaElement.JAVA_MODEL
+				&& type != IJavaElement.JAVA_PROJECT
+				&& type != IJavaElement.PACKAGE_FRAGMENT_ROOT)
+			root = JavaModelUtil.getPackageFragmentRoot(element);
+		if (root != null && getFlag(flags, JavaElementLabels.PREPEND_ROOT_PATH)) {
+			appendPackageFragmentRootLabel(root,
+					JavaElementLabels.ROOT_QUALIFIED);
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+		}
+
+		switch (type) {
+		case IJavaElement.METHOD:
+			appendMethodLabel((IMethod) element, flags);
+			break;
+		case IJavaElement.FIELD:
+			appendFieldLabel((IField) element, flags);
+			break;
+		case IJavaElement.LOCAL_VARIABLE:
+			appendLocalVariableLabel((ILocalVariable) element, flags);
+			break;
+		case IJavaElement.TYPE_PARAMETER:
+			appendTypeParameterLabel((ITypeParameter) element, flags);
+			break;
+		case IJavaElement.INITIALIZER:
+			appendInitializerLabel((IInitializer) element, flags);
+			break;
+		case IJavaElement.TYPE:
+			appendTypeLabel((IType) element, flags);
+			break;
+		case IJavaElement.CLASS_FILE:
+			appendClassFileLabel((IClassFile) element, flags);
+			break;
+		case IJavaElement.COMPILATION_UNIT:
+			appendCompilationUnitLabel((ICompilationUnit) element, flags);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT:
+			appendPackageFragmentLabel((IPackageFragment) element, flags);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			appendPackageFragmentRootLabel((IPackageFragmentRoot) element,
+					flags);
+			break;
+		case IJavaElement.IMPORT_CONTAINER:
+		case IJavaElement.IMPORT_DECLARATION:
+		case IJavaElement.PACKAGE_DECLARATION:
+			appendDeclarationLabel(element, flags);
+			break;
+		case IJavaElement.JAVA_PROJECT:
+		case IJavaElement.JAVA_MODEL:
+			fBuffer.append(element.getElementName());
+			break;
+		default:
+			fBuffer.append(element.getElementName());
+		}
+
+		if (root != null && getFlag(flags, JavaElementLabels.APPEND_ROOT_PATH)) {
+			int offset = fBuffer.length();
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			appendPackageFragmentRootLabel(root,
+					JavaElementLabels.ROOT_QUALIFIED);
+
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+
+		}
+	}
+
+	/**
+	 * Appends the label for a import container, import or package declaration.
+	 * Considers the D_* flags.
+	 * 
+	 * @param declaration
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'D_' are
+	 *            considered.
+	 */
+	public void appendDeclarationLabel(IJavaElement declaration, long flags) {
+		if (getFlag(flags, JavaElementLabels.D_QUALIFIED)) {
+			IJavaElement openable = (IJavaElement) declaration.getOpenable();
+			if (openable != null) {
+				appendElementLabel(openable, JavaElementLabels.CF_QUALIFIED
+						| JavaElementLabels.CU_QUALIFIED
+						| (flags & QUALIFIER_FLAGS));
+				fBuffer.append('/');
+			}
+		}
+		if (declaration.getElementType() == IJavaElement.IMPORT_CONTAINER) {
+			fBuffer.append(messages.JavaElementLabels_import_container());
+		} else {
+			fBuffer.append(declaration.getElementName());
+		}
+		// post qualification
+		if (getFlag(flags, JavaElementLabels.D_POST_QUALIFIED)) {
+			int offset = fBuffer.length();
+			IJavaElement openable = (IJavaElement) declaration.getOpenable();
+			if (openable != null) {
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				appendElementLabel(openable, JavaElementLabels.CF_QUALIFIED
+						| JavaElementLabels.CU_QUALIFIED
+						| (flags & QUALIFIER_FLAGS));
+			}
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	/**
+	 * Appends the label for a compilation unit. Considers the CU_* flags.
+	 * 
+	 * @param cu
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'CU_' are
+	 *            considered.
+	 */
+	public void appendCompilationUnitLabel(ICompilationUnit cu, long flags) {
+		if (getFlag(flags, JavaElementLabels.CU_QUALIFIED)) {
+			IPackageFragment pack = (IPackageFragment) cu.getParent();
+			if (!pack.isDefaultPackage()) {
+				appendPackageFragmentLabel(pack, (flags & QUALIFIER_FLAGS));
+				fBuffer.append('.');
+			}
+		}
+		fBuffer.append(cu.getElementName());
+
+		if (getFlag(flags, JavaElementLabels.CU_POST_QUALIFIED)) {
+			int offset = fBuffer.length();
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			appendPackageFragmentLabel((IPackageFragment) cu.getParent(), flags
+					& QUALIFIER_FLAGS);
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	/**
+	 * Appends the label for a class file. Considers the CF_* flags.
+	 * 
+	 * @param classFile
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'CF_' are
+	 *            considered.
+	 */
+	public void appendClassFileLabel(IClassFile classFile, long flags) {
+		if (getFlag(flags, JavaElementLabels.CF_QUALIFIED)) {
+			IPackageFragment pack = (IPackageFragment) classFile.getParent();
+			if (!pack.isDefaultPackage()) {
+				appendPackageFragmentLabel(pack, (flags & QUALIFIER_FLAGS));
+				fBuffer.append('.');
+			}
+		}
+		fBuffer.append(classFile.getElementName());
+
+		if (getFlag(flags, JavaElementLabels.CF_POST_QUALIFIED)) {
+			int offset = fBuffer.length();
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			appendPackageFragmentLabel(
+					(IPackageFragment) classFile.getParent(), flags
+							& QUALIFIER_FLAGS);
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	/**
+	 * Appends the label for a initializer. Considers the I_* flags.
+	 * 
+	 * @param initializer
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'I_' are
+	 *            considered.
+	 */
+	public void appendInitializerLabel(IInitializer initializer, long flags) {
+		// qualification
+		if (getFlag(flags, JavaElementLabels.I_FULLY_QUALIFIED)) {
+			appendTypeLabel(initializer.getDeclaringType(),
+					JavaElementLabels.T_FULLY_QUALIFIED
+							| (flags & QUALIFIER_FLAGS));
+			fBuffer.append('.');
+		}
+		fBuffer.append(messages.JavaElementLabels_initializer());
+
+		// post qualification
+		if (getFlag(flags, JavaElementLabels.I_POST_QUALIFIED)) {
+			int offset = fBuffer.length();
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			appendTypeLabel(initializer.getDeclaringType(),
+					JavaElementLabels.T_FULLY_QUALIFIED
+							| (flags & QUALIFIER_FLAGS));
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	/**
+	 * Appends the styled label for a type parameter.
+	 * 
+	 * @param typeParameter
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'T_' are
+	 *            considered.
+	 */
+	public void appendTypeParameterLabel(ITypeParameter typeParameter,
+			long flags) {
+		try {
+			fBuffer.append(getElementName(typeParameter));
+
+			if (typeParameter.exists()) {
+				String[] bounds = typeParameter.getBoundsSignatures();
+				if (bounds.length > 0
+						&& !(bounds.length == 1 && "Ljava.lang.Object;".equals(bounds[0]))) { //$NON-NLS-1$
+					fBuffer.append(" extends "); //$NON-NLS-1$
+					for (int j = 0; j < bounds.length; j++) {
+						if (j > 0) {
+							fBuffer.append(JavaElementLabels.COMMA_STRING);
+						}
+						appendTypeSignatureLabel(typeParameter, bounds[j],
+								flags);
+					}
+				}
+			}
+
+			// post qualification
+			if (getFlag(flags, JavaElementLabels.TP_POST_QUALIFIED)) {
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				IMember declaringMember = typeParameter.getDeclaringMember();
+				appendElementLabel(declaringMember,
+						JavaElementLabels.M_PARAMETER_TYPES
+								| JavaElementLabels.M_FULLY_QUALIFIED
+								| JavaElementLabels.T_FULLY_QUALIFIED
+								| (flags & QUALIFIER_FLAGS));
+			}
+
+		} catch (JavaModelException e) {
+			logger.error(e);
+		}
+	}
+
+	/**
+	 * Appends the style label for a field. Considers the F_* flags.
+	 * 
+	 * @param field
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'F_' are
+	 *            considered.
+	 */
+	public void appendFieldLabel(IField field, long flags) {
+		try {
+
+			if (getFlag(flags, JavaElementLabels.F_PRE_TYPE_SIGNATURE)
+					&& field.exists() && !Flags.isEnum(field.getFlags())) {
+				if (getFlag(flags, JavaElementLabels.USE_RESOLVED)
+						&& field.isResolved()) {
+					appendTypeSignatureLabel(field,
+							new BindingKey(field.getKey()).toSignature(), flags);
+				} else {
+					appendTypeSignatureLabel(field, field.getTypeSignature(),
+							flags);
+				}
+				fBuffer.append(' ');
+			}
+
+			// qualification
+			if (getFlag(flags, JavaElementLabels.F_FULLY_QUALIFIED)) {
+				appendTypeLabel(field.getDeclaringType(),
+						JavaElementLabels.T_FULLY_QUALIFIED
+								| (flags & QUALIFIER_FLAGS));
+				fBuffer.append('.');
+			}
+			fBuffer.append(getElementName(field));
+
+			if (getFlag(flags, JavaElementLabels.F_APP_TYPE_SIGNATURE)
+					&& field.exists() && !Flags.isEnum(field.getFlags())) {
+				int offset = fBuffer.length();
+				fBuffer.append(JavaElementLabels.DECL_STRING);
+				if (getFlag(flags, JavaElementLabels.USE_RESOLVED)
+						&& field.isResolved()) {
+					appendTypeSignatureLabel(field,
+							new BindingKey(field.getKey()).toSignature(), flags);
+				} else {
+					appendTypeSignatureLabel(field, field.getTypeSignature(),
+							flags);
+				}
+				if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+					fBuffer.setStyle(offset, fBuffer.length() - offset,
+							DECORATIONS_STYLE);
+				}
+			}
+
+			// category
+			if (getFlag(flags, JavaElementLabels.F_CATEGORY) && field.exists())
+				appendCategoryLabel(field, flags);
+
+			// post qualification
+			if (getFlag(flags, JavaElementLabels.F_POST_QUALIFIED)) {
+				int offset = fBuffer.length();
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				appendTypeLabel(field.getDeclaringType(),
+						JavaElementLabels.T_FULLY_QUALIFIED
+								| (flags & QUALIFIER_FLAGS));
+				if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+					fBuffer.setStyle(offset, fBuffer.length() - offset,
+							QUALIFIER_STYLE);
+				}
+			}
+
+		} catch (JavaModelException e) {
+			logger.error(e);
+		}
+	}
+
+	/**
+	 * Returns <code>true</code> if the given package fragment root is
+	 * referenced. This means it is a descendant of a different project but is
+	 * referenced by the root's parent. Returns <code>false</code> if the given
+	 * root doesn't have an underlying resource.
+	 * 
+	 * @param root
+	 *            the package fragment root
+	 * @return returns <code>true</code> if the given package fragment root is
+	 *         referenced
+	 */
+	private boolean isReferenced(IPackageFragmentRoot root) {
+		IResource resource = root.getResource();
+		if (resource != null) {
+			IProject jarProject = resource.getProject();
+			IProject container = root.getJavaProject().getProject();
+			return !container.equals(jarProject);
+		}
+		return false;
+	}
+
+	private void appendInternalArchiveLabel(IPackageFragmentRoot root,
+			long flags) {
+		IResource resource = root.getResource();
+		boolean rootQualified = getFlag(flags, JavaElementLabels.ROOT_QUALIFIED);
+		if (rootQualified) {
+			fBuffer.append(root.getPath().makeRelative().toString());
+		} else {
+			fBuffer.append(root.getElementName());
+			int offset = fBuffer.length();
+			boolean referencedPostQualified = getFlag(flags,
+					JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED);
+			if (referencedPostQualified && isReferenced(root)) {
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				fBuffer.append(resource.getParent().getFullPath()
+						.makeRelative().toString());
+			} else if (getFlag(flags, JavaElementLabels.ROOT_POST_QUALIFIED)) {
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				fBuffer.append(root.getParent().getPath().makeRelative()
+						.toString());
+			}
+			if (referencedPostQualified) {
+				try {
+					IClasspathEntry referencingEntry = JavaModelUtil
+							.getClasspathEntry(root).getReferencingEntry();
+					if (referencingEntry != null) {
+						fBuffer.append(messages
+								.JavaElementLabels_onClassPathOf(
+										Name.CLASS_PATH.toString(),
+										referencingEntry.getPath()
+												.lastSegment()));
+					}
+				} catch (JavaModelException e) {
+					// ignore
+				}
+			}
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	/**
+	 * Appends the label for a method. Considers the M_* flags.
+	 * 
+	 * @param method
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'M_' are
+	 *            considered.
+	 */
+	public void appendMethodLabel(IMethod method, long flags) {
+		try {
+			BindingKey resolvedKey = getFlag(flags,
+					JavaElementLabels.USE_RESOLVED) && method.isResolved() ? new BindingKey(
+					method.getKey()) : null;
+			String resolvedSig = (resolvedKey != null) ? resolvedKey
+					.toSignature() : null;
+
+			// type parameters
+			if (getFlag(flags, JavaElementLabels.M_PRE_TYPE_PARAMETERS)) {
+				if (resolvedKey != null) {
+					if (resolvedKey.isParameterizedMethod()) {
+						String[] typeArgRefs = resolvedKey.getTypeArguments();
+						if (typeArgRefs.length > 0) {
+							appendTypeArgumentSignaturesLabel(method,
+									typeArgRefs, flags);
+							fBuffer.append(' ');
+						}
+					} else {
+						String[] typeParameterSigs = Signature
+								.getTypeParameters(resolvedSig);
+						if (typeParameterSigs.length > 0) {
+							appendTypeParameterSignaturesLabel(
+									typeParameterSigs, flags);
+							fBuffer.append(' ');
+						}
+					}
+				} else if (method.exists()) {
+					ITypeParameter[] typeParameters = method
+							.getTypeParameters();
+					if (typeParameters.length > 0) {
+						appendTypeParametersLabels(typeParameters, flags);
+						fBuffer.append(' ');
+					}
+				}
+			}
+
+			// return type
+			if (getFlag(flags, JavaElementLabels.M_PRE_RETURNTYPE)
+					&& method.exists() && !method.isConstructor()) {
+				String returnTypeSig = resolvedSig != null ? Signature
+						.getReturnType(resolvedSig) : method.getReturnType();
+				appendTypeSignatureLabel(method, returnTypeSig, flags);
+				fBuffer.append(' ');
+			}
+
+			// qualification
+			if (getFlag(flags, JavaElementLabels.M_FULLY_QUALIFIED)) {
+				appendTypeLabel(method.getDeclaringType(),
+						JavaElementLabels.T_FULLY_QUALIFIED
+								| (flags & QUALIFIER_FLAGS));
+				fBuffer.append('.');
+			}
+
+			fBuffer.append(getElementName(method));
+
+			// parameters
+			fBuffer.append('(');
+			if (getFlag(flags, JavaElementLabels.M_PARAMETER_TYPES
+					| JavaElementLabels.M_PARAMETER_NAMES)) {
+				String[] types = null;
+				int nParams = 0;
+				boolean renderVarargs = false;
+				if (getFlag(flags, JavaElementLabels.M_PARAMETER_TYPES)) {
+					if (resolvedSig != null) {
+						types = Signature.getParameterTypes(resolvedSig);
+					} else {
+						types = method.getParameterTypes();
+					}
+					nParams = types.length;
+					renderVarargs = method.exists()
+							&& Flags.isVarargs(method.getFlags());
+				}
+				String[] names = null;
+				if (getFlag(flags, JavaElementLabels.M_PARAMETER_NAMES)
+						&& method.exists()) {
+					names = method.getParameterNames();
+					if (types == null) {
+						nParams = names.length;
+					} else { // types != null
+						if (nParams != names.length) {
+							if (resolvedSig != null
+									&& types.length > names.length) {
+								// see
+								// https://bugs.eclipse.org/bugs/show_bug.cgi?id=99137
+								nParams = names.length;
+								String[] typesWithoutSyntheticParams = new String[nParams];
+								System.arraycopy(types, types.length - nParams,
+										typesWithoutSyntheticParams, 0, nParams);
+								types = typesWithoutSyntheticParams;
+							} else {
+								// https://bugs.eclipse.org/bugs/show_bug.cgi?id=101029
+								// JavaPlugin.logErrorMessage("JavaElementLabels: Number of param types(" + nParams + ") != number of names(" + names.length + "): " + method.getElementName());   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+								names = null; // no names rendered
+							}
+						}
+					}
+				}
+
+				for (int i = 0; i < nParams; i++) {
+					if (i > 0) {
+						fBuffer.append(JavaElementLabels.COMMA_STRING);
+					}
+					if (types != null) {
+						String paramSig = types[i];
+						if (renderVarargs && (i == nParams - 1)) {
+							int newDim = Signature.getArrayCount(paramSig) - 1;
+							appendTypeSignatureLabel(method,
+									Signature.getElementType(paramSig), flags);
+							for (int k = 0; k < newDim; k++) {
+								fBuffer.append('[').append(']');
+							}
+							fBuffer.append(JavaElementLabels.ELLIPSIS_STRING);
+						} else {
+							appendTypeSignatureLabel(method, paramSig, flags);
+						}
+					}
+					if (names != null) {
+						if (types != null) {
+							fBuffer.append(' ');
+						}
+						fBuffer.append(names[i]);
+					}
+				}
+			} else {
+				if (method.getParameterTypes().length > 0) {
+					fBuffer.append(JavaElementLabels.ELLIPSIS_STRING);
+				}
+			}
+			fBuffer.append(')');
+
+			if (getFlag(flags, JavaElementLabels.M_EXCEPTIONS)) {
+				String[] types;
+				if (resolvedKey != null) {
+					types = resolvedKey.getThrownExceptions();
+				} else {
+					types = method.exists() ? method.getExceptionTypes()
+							: new String[0];
+				}
+				if (types.length > 0) {
+					fBuffer.append(" throws "); //$NON-NLS-1$
+					for (int i = 0; i < types.length; i++) {
+						if (i > 0) {
+							fBuffer.append(JavaElementLabels.COMMA_STRING);
+						}
+						appendTypeSignatureLabel(method, types[i], flags);
+					}
+				}
+			}
+
+			if (getFlag(flags, JavaElementLabels.M_APP_TYPE_PARAMETERS)) {
+				int offset = fBuffer.length();
+				if (resolvedKey != null) {
+					if (resolvedKey.isParameterizedMethod()) {
+						String[] typeArgRefs = resolvedKey.getTypeArguments();
+						if (typeArgRefs.length > 0) {
+							fBuffer.append(' ');
+							appendTypeArgumentSignaturesLabel(method,
+									typeArgRefs, flags);
+						}
+					} else {
+						String[] typeParameterSigs = Signature
+								.getTypeParameters(resolvedSig);
+						if (typeParameterSigs.length > 0) {
+							fBuffer.append(' ');
+							appendTypeParameterSignaturesLabel(
+									typeParameterSigs, flags);
+						}
+					}
+				} else if (method.exists()) {
+					ITypeParameter[] typeParameters = method
+							.getTypeParameters();
+					if (typeParameters.length > 0) {
+						fBuffer.append(' ');
+						appendTypeParametersLabels(typeParameters, flags);
+					}
+				}
+				if (getFlag(flags, JavaElementLabels.COLORIZE)
+						&& offset != fBuffer.length()) {
+					fBuffer.setStyle(offset, fBuffer.length() - offset,
+							DECORATIONS_STYLE);
+				}
+			}
+
+			if (getFlag(flags, JavaElementLabels.M_APP_RETURNTYPE)
+					&& method.exists() && !method.isConstructor()) {
+				int offset = fBuffer.length();
+				fBuffer.append(JavaElementLabels.DECL_STRING);
+				String returnTypeSig = resolvedSig != null ? Signature
+						.getReturnType(resolvedSig) : method.getReturnType();
+				appendTypeSignatureLabel(method, returnTypeSig, flags);
+				if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+					fBuffer.setStyle(offset, fBuffer.length() - offset,
+							DECORATIONS_STYLE);
+				}
+			}
+
+			// category
+			if (getFlag(flags, JavaElementLabels.M_CATEGORY) && method.exists())
+				appendCategoryLabel(method, flags);
+
+			// post qualification
+			if (getFlag(flags, JavaElementLabels.M_POST_QUALIFIED)) {
+				int offset = fBuffer.length();
+				fBuffer.append(JavaElementLabels.CONCAT_STRING);
+				appendTypeLabel(method.getDeclaringType(),
+						JavaElementLabels.T_FULLY_QUALIFIED
+								| (flags & QUALIFIER_FLAGS));
+				if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+					fBuffer.setStyle(offset, fBuffer.length() - offset,
+							QUALIFIER_STYLE);
+				}
+			}
+
+		} catch (JavaModelException e) {
+			logger.error(e);
+		}
+	}
+
+	protected void appendTypeSignatureLabel(IJavaElement enclosingElement,
+			String typeSig, long flags) {
+		int sigKind = Signature.getTypeSignatureKind(typeSig);
+		switch (sigKind) {
+		case Signature.BASE_TYPE_SIGNATURE:
+			fBuffer.append(Signature.toString(typeSig));
+			break;
+		case Signature.ARRAY_TYPE_SIGNATURE:
+			appendTypeSignatureLabel(enclosingElement,
+					Signature.getElementType(typeSig), flags);
+			for (int dim = Signature.getArrayCount(typeSig); dim > 0; dim--) {
+				fBuffer.append('[').append(']');
+			}
+			break;
+		case Signature.CLASS_TYPE_SIGNATURE:
+			String baseType = getSimpleTypeName(enclosingElement,
+					Signature.getTypeErasure(typeSig));
+			fBuffer.append(baseType);
+
+			String[] typeArguments = Signature.getTypeArguments(typeSig);
+			appendTypeArgumentSignaturesLabel(enclosingElement, typeArguments,
+					flags);
+			break;
+		case Signature.TYPE_VARIABLE_SIGNATURE:
+			fBuffer.append(getSimpleTypeName(enclosingElement, typeSig));
+			break;
+		case Signature.WILDCARD_TYPE_SIGNATURE:
+			char ch = typeSig.charAt(0);
+			if (ch == Signature.C_STAR) { // workaround for bug 85713
+				fBuffer.append('?');
+			} else {
+				if (ch == Signature.C_EXTENDS) {
+					fBuffer.append("? extends "); //$NON-NLS-1$
+					appendTypeSignatureLabel(enclosingElement,
+							typeSig.substring(1), flags);
+				} else if (ch == Signature.C_SUPER) {
+					fBuffer.append("? super "); //$NON-NLS-1$
+					appendTypeSignatureLabel(enclosingElement,
+							typeSig.substring(1), flags);
+				}
+			}
+			break;
+		case Signature.CAPTURE_TYPE_SIGNATURE:
+			appendTypeSignatureLabel(enclosingElement, typeSig.substring(1),
+					flags);
+			break;
+		default:
+			// unknown
+		}
+	}
+
+	/**
+	 * Returns the simple name of the given type signature.
+	 * 
+	 * @param enclosingElement
+	 *            the enclosing element in which to resolve the signature
+	 * @param typeSig
+	 *            a {@link Signature#CLASS_TYPE_SIGNATURE} or
+	 *            {@link Signature#TYPE_VARIABLE_SIGNATURE}
+	 * @return the simple name of the given type signature
+	 */
+	protected String getSimpleTypeName(IJavaElement enclosingElement,
+			String typeSig) {
+		return Signature.getSimpleName(Signature.toString(typeSig));
+	}
+
+	private void appendTypeArgumentSignaturesLabel(
+			IJavaElement enclosingElement, String[] typeArgsSig, long flags) {
+		if (typeArgsSig.length > 0) {
+			fBuffer.append(getLT());
+			for (int i = 0; i < typeArgsSig.length; i++) {
+				if (i > 0) {
+					fBuffer.append(JavaElementLabels.COMMA_STRING);
+				}
+				appendTypeSignatureLabel(enclosingElement, typeArgsSig[i],
+						flags);
+			}
+			fBuffer.append(getGT());
+		}
+	}
+
+	/**
+	 * Returns the string for rendering the '<code>&lt;</code>' character.
+	 * 
+	 * @return the string for rendering '<code>&lt;</code>'
+	 */
+	protected String getLT() {
+		return "<"; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the string for rendering the '<code>&gt;</code>' character.
+	 * 
+	 * @return the string for rendering '<code>&gt;</code>'
+	 */
+	protected String getGT() {
+		return ">"; //$NON-NLS-1$
+	}
+
+	/**
+	 * Appends labels for type parameters from a signature.
+	 * 
+	 * @param typeParamSigs
+	 *            the type parameter signature
+	 * @param flags
+	 *            flags with render options
+	 */
+	private void appendTypeParameterSignaturesLabel(String[] typeParamSigs,
+			long flags) {
+		if (typeParamSigs.length > 0) {
+			fBuffer.append(getLT());
+			for (int i = 0; i < typeParamSigs.length; i++) {
+				if (i > 0) {
+					fBuffer.append(JavaElementLabels.COMMA_STRING);
+				}
+				fBuffer.append(Signature.getTypeVariable(typeParamSigs[i]));
+			}
+			fBuffer.append(getGT());
+		}
+	}
+
+	/**
+	 * Appends labels for type parameters from type binding array.
+	 * 
+	 * @param typeParameters
+	 *            the type parameters
+	 * @param flags
+	 *            flags with render options
+	 */
+	private void appendTypeParametersLabels(ITypeParameter[] typeParameters,
+			long flags) {
+		if (typeParameters.length > 0) {
+			fBuffer.append(getLT());
+			for (int i = 0; i < typeParameters.length; i++) {
+				if (i > 0) {
+					fBuffer.append(JavaElementLabels.COMMA_STRING);
+				}
+				fBuffer.append(getElementName(typeParameters[i]));
+			}
+			fBuffer.append(getGT());
+		}
+	}
+
+	/**
+	 * Returns the string for rendering the
+	 * {@link IJavaElement#getElementName() element name} of the given element.
+	 * 
+	 * @param element
+	 *            the element to render
+	 * @return the string for rendering the element name
+	 */
+	protected String getElementName(IJavaElement element) {
+		return element.getElementName();
+	}
+
+	private void appendCategoryLabel(IMember member, long flags)
+			throws JavaModelException {
+		String[] categories = member.getCategories();
+		if (categories.length > 0) {
+			int offset = fBuffer.length();
+			StringBuffer categoriesBuf = new StringBuffer();
+			for (int i = 0; i < categories.length; i++) {
+				if (i > 0)
+					categoriesBuf
+							.append(JavaElementLabels.CATEGORY_SEPARATOR_STRING);
+				categoriesBuf.append(categories[i]);
+			}
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			fBuffer.append(messages.JavaElementLabels_category(categoriesBuf
+					.toString()));
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						COUNTER_STYLE);
+			}
+		}
+	}
+
+	/**
+	 * Appends the label for a type. Considers the T_* flags.
+	 * 
+	 * @param type
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'T_' are
+	 *            considered.
+	 */
+	public void appendTypeLabel(IType type, long flags) {
+
+		if (getFlag(flags, JavaElementLabels.T_FULLY_QUALIFIED)) {
+			IPackageFragment pack = type.getPackageFragment();
+			if (!pack.isDefaultPackage()) {
+				appendPackageFragmentLabel(pack, (flags & QUALIFIER_FLAGS));
+				fBuffer.append('.');
+			}
+		}
+		if (getFlag(flags, JavaElementLabels.T_FULLY_QUALIFIED
+				| JavaElementLabels.T_CONTAINER_QUALIFIED)) {
+			IType declaringType = type.getDeclaringType();
+			if (declaringType != null) {
+				appendTypeLabel(declaringType,
+						JavaElementLabels.T_CONTAINER_QUALIFIED
+								| (flags & QUALIFIER_FLAGS));
+				fBuffer.append('.');
+			}
+			int parentType = type.getParent().getElementType();
+			if (parentType == IJavaElement.METHOD
+					|| parentType == IJavaElement.FIELD
+					|| parentType == IJavaElement.INITIALIZER) { // anonymous or
+																	// local
+				appendElementLabel(type.getParent(), 0);
+				fBuffer.append('.');
+			}
+		}
+
+		String typeName = getElementName(type);
+		if (typeName.length() == 0) { // anonymous
+			try {
+				if (type.getParent() instanceof IField && type.isEnum()) {
+					typeName = '{' + JavaElementLabels.ELLIPSIS_STRING + '}';
+				} else {
+					String supertypeName;
+					String[] superInterfaceSignatures = type
+							.getSuperInterfaceTypeSignatures();
+					if (superInterfaceSignatures.length > 0) {
+						supertypeName = getSimpleTypeName(type,
+								superInterfaceSignatures[0]);
+					} else {
+						supertypeName = getSimpleTypeName(type,
+								type.getSuperclassTypeSignature());
+					}
+					typeName = messages
+							.JavaElementLabels_anonym_type(supertypeName);
+				}
+			} catch (JavaModelException e) {
+				// ignore
+				typeName = messages.JavaElementLabels_anonym();
+			}
+		}
+		fBuffer.append(typeName);
+		if (getFlag(flags, JavaElementLabels.T_TYPE_PARAMETERS)) {
+			if (getFlag(flags, JavaElementLabels.USE_RESOLVED)
+					&& type.isResolved()) {
+				BindingKey key = new BindingKey(type.getKey());
+				if (key.isParameterizedType()) {
+					String[] typeArguments = key.getTypeArguments();
+					appendTypeArgumentSignaturesLabel(type, typeArguments,
+							flags);
+				} else {
+					String[] typeParameters = Signature.getTypeParameters(key
+							.toSignature());
+					appendTypeParameterSignaturesLabel(typeParameters, flags);
+				}
+			} else if (type.exists()) {
+				try {
+					appendTypeParametersLabels(type.getTypeParameters(), flags);
+				} catch (JavaModelException e) {
+					// ignore
+				}
+			}
+		}
+
+		// category
+		if (getFlag(flags, JavaElementLabels.T_CATEGORY) && type.exists()) {
+			try {
+				appendCategoryLabel(type, flags);
+			} catch (JavaModelException e) {
+				// ignore
+			}
+		}
+
+		// post qualification
+		if (getFlag(flags, JavaElementLabels.T_POST_QUALIFIED)) {
+			int offset = fBuffer.length();
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			IType declaringType = type.getDeclaringType();
+			if (declaringType != null) {
+				appendTypeLabel(declaringType,
+						JavaElementLabels.T_FULLY_QUALIFIED
+								| (flags & QUALIFIER_FLAGS));
+				int parentType = type.getParent().getElementType();
+				if (parentType == IJavaElement.METHOD
+						|| parentType == IJavaElement.FIELD
+						|| parentType == IJavaElement.INITIALIZER) { // anonymous
+																		// or
+																		// local
+					fBuffer.append('.');
+					appendElementLabel(type.getParent(), 0);
+				}
+			} else {
+				appendPackageFragmentLabel(type.getPackageFragment(), flags
+						& QUALIFIER_FLAGS);
+			}
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	/**
+	 * Appends the styled label for a local variable.
+	 * 
+	 * @param localVariable
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with 'F_' are
+	 *            considered.
+	 */
+	public void appendLocalVariableLabel(ILocalVariable localVariable,
+			long flags) {
+		if (getFlag(flags, JavaElementLabels.F_PRE_TYPE_SIGNATURE)) {
+			appendTypeSignatureLabel(localVariable,
+					localVariable.getTypeSignature(), flags);
+			fBuffer.append(' ');
+		}
+
+		if (getFlag(flags, JavaElementLabels.F_FULLY_QUALIFIED)) {
+			appendElementLabel(localVariable.getParent(),
+					JavaElementLabels.M_PARAMETER_TYPES
+							| JavaElementLabels.M_FULLY_QUALIFIED
+							| JavaElementLabels.T_FULLY_QUALIFIED
+							| (flags & QUALIFIER_FLAGS));
+			fBuffer.append('.');
+		}
+
+		fBuffer.append(getElementName(localVariable));
+
+		if (getFlag(flags, JavaElementLabels.F_APP_TYPE_SIGNATURE)) {
+			int offset = fBuffer.length();
+			fBuffer.append(JavaElementLabels.DECL_STRING);
+			appendTypeSignatureLabel(localVariable,
+					localVariable.getTypeSignature(), flags);
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						DECORATIONS_STYLE);
+			}
+		}
+
+		// post qualification
+		if (getFlag(flags, JavaElementLabels.F_POST_QUALIFIED)) {
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			appendElementLabel(localVariable.getParent(),
+					JavaElementLabels.M_PARAMETER_TYPES
+							| JavaElementLabels.M_FULLY_QUALIFIED
+							| JavaElementLabels.T_FULLY_QUALIFIED
+							| (flags & QUALIFIER_FLAGS));
+		}
+	}
+
+	/**
+	 * Appends the label for a package fragment. Considers the P_* flags.
+	 * 
+	 * @param pack
+	 *            the element to render
+	 * @param flags
+	 *            the rendering flags. Flags with names starting with P_' are
+	 *            considered.
+	 */
+	public void appendPackageFragmentLabel(IPackageFragment pack, long flags) {
+		if (getFlag(flags, JavaElementLabels.P_QUALIFIED)) {
+			appendPackageFragmentRootLabel(
+					(IPackageFragmentRoot) pack.getParent(),
+					JavaElementLabels.ROOT_QUALIFIED);
+			fBuffer.append('/');
+		}
+		if (pack.isDefaultPackage()) {
+			fBuffer.append(JavaElementLabels.DEFAULT_PACKAGE);
+			// TODO } else if (getFlag(flags, JavaElementLabels.P_COMPRESSED)) {
+			// if (isPackageNameAbbreviationEnabled())
+			// appendAbbreviatedPackageFragment(pack);
+			// else
+			// appendCompressedPackageFragment(pack);
+		} else {
+			fBuffer.append(pack.getElementName());
+		}
+		if (getFlag(flags, JavaElementLabels.P_POST_QUALIFIED)) {
+			int offset = fBuffer.length();
+			fBuffer.append(JavaElementLabels.CONCAT_STRING);
+			appendPackageFragmentRootLabel(
+					(IPackageFragmentRoot) pack.getParent(),
+					JavaElementLabels.ROOT_QUALIFIED);
+			if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+				fBuffer.setStyle(offset, fBuffer.length() - offset,
+						QUALIFIER_STYLE);
+			}
+		}
+	}
+
+	// private void appendCompressedPackageFragment(String elementName) {
+	// refreshPackageNamePattern();
+	// if (fgPkgNameLength < 0) {
+	// fBuffer.append(elementName);
+	// return;
+	// }
+	// String name= elementName;
+	// int start= 0;
+	// int dot= name.indexOf('.', start);
+	// while (dot > 0) {
+	// if (dot - start > fgPkgNameLength-1) {
+	// fBuffer.append(fgPkgNamePrefix);
+	// if (fgPkgNameChars > 0)
+	// fBuffer.append(name.substring(start, Math.min(start+ fgPkgNameChars,
+	// dot)));
+	// fBuffer.append(fgPkgNamePostfix);
+	// } else
+	// fBuffer.append(name.substring(start, dot + 1));
+	// start= dot + 1;
+	// dot= name.indexOf('.', start);
+	// }
+	// fBuffer.append(name.substring(start));
+	// }
+
+	// private boolean isPackageNameAbbreviationEnabled() {
+	// return false;
+	// //TODO IPreferenceStore store= PreferenceConstants.getPreferenceStore();
+	// // return
+	// store.getBoolean(JavaElementLabelComposer.APPEARANCE_ABBREVIATE_PACKAGE_NAMES);
+	// }
+
+	// private void appendAbbreviatedPackageFragment(IPackageFragment pack) {
+	// refreshPackageNameAbbreviation();
+	//
+	// String pkgName= pack.getElementName();
+	//
+	// if (fgPkgNameAbbreviation != null && fgPkgNameAbbreviation.length != 0) {
+	//
+	// for (int i= 0; i < fgPkgNameAbbreviation.length; i++) {
+	// PackageNameAbbreviation abbr= fgPkgNameAbbreviation[i];
+	//
+	// String abbrPrefix= abbr.getPackagePrefix();
+	// if (pkgName.startsWith(abbrPrefix)) {
+	// int abbrPrefixLength= abbrPrefix.length();
+	// int pkgLength= pkgName.length();
+	// if (!(pkgLength == abbrPrefixLength || pkgName.charAt(abbrPrefixLength)
+	// == '.'))
+	// continue;
+	//
+	// fBuffer.append(abbr.getAbbreviation());
+	//
+	// if (pkgLength > abbrPrefixLength) {
+	// fBuffer.append('.');
+	//
+	// String remaining= pkgName.substring(abbrPrefixLength + 1);
+	//
+	// if (isPackageNameCompressionEnabled())
+	// appendCompressedPackageFragment(remaining);
+	// else
+	// fBuffer.append(remaining);
+	// }
+	//
+	// return;
+	// }
+	// }
+	// }
+	//
+	// if (isPackageNameCompressionEnabled()) {
+	// appendCompressedPackageFragment(pkgName);
+	// } else {
+	// fBuffer.append(pkgName);
+	// }
+	// }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabels.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabels.java
new file mode 100644
index 0000000..78d9540
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabels.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.osgi.util.TextProcessor;
+
+public class JavaElementLabels {
+	/**
+	 * Method names contain parameter types.
+	 * e.g. <code>foo(int)</code>
+	 */
+	public final static long M_PARAMETER_TYPES= 1L << 0;
+	
+	/**
+	 * Method names contain parameter names.
+	 * e.g. <code>foo(index)</code>
+	 */
+	public final static long M_PARAMETER_NAMES= 1L << 1;
+
+	/**
+	 * Method names contain type parameters prepended.
+	 * e.g. <code>&lt;A&gt; foo(A index)</code>
+	 */
+	public final static long M_PRE_TYPE_PARAMETERS= 1L << 2;
+
+	
+	/**
+	 * Method names contain type parameters appended.
+	 * e.g. <code>foo(A index) &lt;A&gt;</code>
+	 */
+	public final static long M_APP_TYPE_PARAMETERS= 1L << 3;
+
+	/**
+	 * Method names contain thrown exceptions.
+	 * e.g. <code>foo throws IOException</code>
+	 */
+	public final static long M_EXCEPTIONS= 1L << 4;
+
+	/**
+	 * Method names contain return type (appended)
+	 * e.g. <code>foo : int</code>
+	 */
+	public final static long M_APP_RETURNTYPE= 1L << 5;
+
+	
+	/**
+	 * Method names contain return type (appended)
+	 * e.g. <code>int foo</code>
+	 */
+	public final static long M_PRE_RETURNTYPE= 1L << 6;
+
+	/**
+	 * Method names are fully qualified.
+	 * e.g. <code>java.util.Vector.size</code>
+	 */
+	public final static long M_FULLY_QUALIFIED= 1L << 7;
+
+	/**
+	 * Method names are post qualified.
+	 * e.g. <code>size - java.util.Vector</code>
+	 */
+	public final static long M_POST_QUALIFIED= 1L << 8;
+
+	/**
+	 * Initializer names are fully qualified.
+	 * e.g. <code>java.util.Vector.{ ... }</code>
+	 */
+	public final static long I_FULLY_QUALIFIED= 1L << 10;
+
+	/**
+	 * Type names are post qualified.
+	 * e.g. <code>{ ... } - java.util.Map</code>
+	 */
+	public final static long I_POST_QUALIFIED= 1L << 11;
+
+	/**
+	 * Field names contain the declared type (appended)
+	 * e.g. <code>fHello : int</code>
+	 */
+	public final static long F_APP_TYPE_SIGNATURE= 1L << 14;
+	
+	/**
+	 * Field names contain the declared type (prepended)
+	 * e.g. <code>int fHello</code>
+	 */
+	public final static long F_PRE_TYPE_SIGNATURE= 1L << 15;
+	
+	/**
+	 * Fields names are fully qualified.
+	 * e.g. <code>java.lang.System.out</code>
+	 */
+	public final static long F_FULLY_QUALIFIED= 1L << 16;
+	/**
+	 * Fields names are post qualified.
+	 * e.g. <code>out - java.lang.System</code>
+	 */
+	public final static long F_POST_QUALIFIED= 1L << 17;
+	/**
+	 * Type names are fully qualified.
+	 * e.g. <code>java.util.Map.Entry</code>
+	 */
+	public final static long T_FULLY_QUALIFIED= 1L << 18;
+
+	/**
+	 * Type names are type container qualified.
+	 * e.g. <code>Map.Entry</code>
+	 */
+	public final static long T_CONTAINER_QUALIFIED= 1L << 19;
+	
+	/**
+	 * Type names are post qualified.
+	 * e.g. <code>Entry - java.util.Map</code>
+	 */
+	public final static long T_POST_QUALIFIED= 1L << 20;
+
+	/**
+	 * Type names contain type parameters.
+	 * e.g. <code>Map&lt;S, T&gt;</code>
+	 */
+	public final static long T_TYPE_PARAMETERS= 1L << 21;
+	
+	/**
+	 * Type parameters are post qualified.
+	 * e.g. <code>K - java.util.Map.Entry</code>
+	 *
+	 * @since 3.5
+	 */
+	public final static long TP_POST_QUALIFIED= 1L << 22;
+	
+	/**
+	 * Declarations (import container / declaration, package declaration) are qualified.
+	 * e.g. <code>java.util.Vector.class/import container</code>
+	 */
+	public final static long D_QUALIFIED= 1L << 24;
+	
+	/**
+	 * Declarations (import container / declaration, package declaration) are post qualified.
+	 * e.g. <code>import container - java.util.Vector.class</code>
+	 */
+	public final static long D_POST_QUALIFIED= 1L << 25;
+	
+	/**
+	 * Class file names are fully qualified.
+	 * e.g. <code>java.util.Vector.class</code>
+	 */
+	public final static long CF_QUALIFIED= 1L << 27;
+	
+	/**
+	 * Class file names are post qualified.
+	 * e.g. <code>Vector.class - java.util</code>
+	 */
+	public final static long CF_POST_QUALIFIED= 1L << 28;
+
+	/**
+	 * Compilation unit names are fully qualified.
+	 * e.g. <code>java.util.Vector.java</code>
+	 */
+	public final static long CU_QUALIFIED= 1L << 31;
+
+	/**
+	 * Compilation unit names are post  qualified.
+	 * e.g. <code>Vector.java - java.util</code>
+	 */
+	public final static long CU_POST_QUALIFIED= 1L << 32;
+
+	
+	/**
+	 * Package names are qualified.
+	 * e.g. <code>MyProject/src/java.util</code>
+	 */
+	public final static long P_QUALIFIED= 1L << 35;
+	
+	/**
+	 * Package names are post qualified.
+	 * e.g. <code>java.util - MyProject/src</code>
+	 */
+	public final static long P_POST_QUALIFIED= 1L << 36;
+	
+	/**
+	 * Package names are compressed.
+	 * e.g. <code>o*.e*.search</code>
+	 */
+	public final static long P_COMPRESSED= 1L << 37;
+	
+	/**
+	 * Package Fragment Roots contain variable name if from a variable.
+	 * e.g. <code>JRE_LIB - c:\java\lib\rt.jar</code>
+	 */
+	public final static long ROOT_VARIABLE= 1L << 40;
+
+	
+	/**
+	 * Package Fragment Roots contain the project name if not an archive (prepended).
+	 * e.g. <code>MyProject/src</code>
+	 */
+	public final static long ROOT_QUALIFIED= 1L << 41;
+
+	/**
+	 * Package Fragment Roots contain the project name if not an archive (appended).
+	 * e.g. <code>src - MyProject</code>
+	 */
+	public final static long ROOT_POST_QUALIFIED= 1L << 42;
+	
+	/**
+	 * Add root path to all elements except Package Fragment Roots and Java projects.
+	 * e.g. <code>java.lang.Vector - C:\java\lib\rt.jar</code>
+	 * Option only applies to getElementLabel
+	 */
+	public final static long APPEND_ROOT_PATH= 1L << 43;
+
+	
+	/**
+	 * Add root path to all elements except Package Fragment Roots and Java projects.
+	 * e.g. <code>C:\java\lib\rt.jar - java.lang.Vector</code>
+	 * Option only applies to getElementLabel
+	 */
+	public final static long PREPEND_ROOT_PATH= 1L << 44;
+
+	/**
+	 * Post qualify referenced package fragment roots. For example
+	 * <code>jdt.jar - org.eclipse.jdt.ui</code> if the jar is referenced
+	 * from another project.
+	 */
+	public final static long REFERENCED_ROOT_POST_QUALIFIED= 1L << 45;
+
+	/**
+	 * Specifies to use the resolved information of a IType, IMethod or IField. See {@link IType#isResolved()}.
+	 * If resolved information is available, types will be rendered with type parameters of the instantiated type.
+	 * Resolved methods render with the parameter types of the method instance.
+	 * <code>Vector&lt;String&gt;.get(String)</code>
+	 */
+	public final static long USE_RESOLVED= 1L << 48;
+	/**
+	 * Prepend first category (if any) to field.
+	 * @since 3.2
+	 */
+	public final static long F_CATEGORY= 1L << 49;
+	/**
+	 * Prepend first category (if any) to method.
+	 * @since 3.2
+	 */
+	public final static long M_CATEGORY= 1L << 50;
+	/**
+	 * Prepend first category (if any) to type.
+	 * @since 3.2
+	 */
+	public final static long T_CATEGORY= 1L << 51;
+	
+	/**
+	 * Specifies to apply color styles to labels. This flag only applies to methods taking or returning a {@link StyledString}.
+	 *
+	 * @since 3.4
+	 */
+	public final static long COLORIZE= 1L << 55;
+
+	/**
+	 * Show category for all elements.
+	 * @since 3.2
+	 */
+	public final static long ALL_CATEGORY= new Long(F_CATEGORY | M_CATEGORY | T_CATEGORY).longValue();
+
+	
+	/**
+	 * User-readable string for concatenating categories (e.g. " ").
+	 * @since 3.5
+	 */
+	public final static String CATEGORY_SEPARATOR_STRING = " "; //JavaUIMessages.JavaElementLabels_category_separator_string;
+	
+	/**
+	 * User-readable string for separating post qualified names (e.g. " - ").
+	 */
+	public final static String CONCAT_STRING = "-"; //TODO JavaUIMessages.JavaElementLabels_concat_string;
+
+	/**
+	 * User-readable string for separating list items (e.g. ", ").
+	 */
+	public final static String COMMA_STRING = ", "; //TODO JavaUIMessages.JavaElementLabels_comma_string;
+
+	/**
+	 * User-readable string for separating the return type (e.g. " : ").
+	 */
+	public final static String DECL_STRING= ": "; //TODO JavaUIMessages.JavaElementLabels_declseparator_string;
+	
+	/**
+	 * User-readable string for ellipsis ("...").
+	 */
+	public final static String ELLIPSIS_STRING= "..."; //$NON-NLS-1$
+
+	/**
+	 * User-readable string for the default package name (e.g. "(default package)").
+	 */
+	public final static String DEFAULT_PACKAGE= "(default package)"; //TODO JavaUIMessages.JavaElementLabels_default_package;
+
+	/**
+	 *  Default options (M_PARAMETER_TYPES,  M_APP_TYPE_PARAMETERS & T_TYPE_PARAMETERS enabled)
+	 */
+	public final static long ALL_DEFAULT= new Long(M_PARAMETER_TYPES | M_APP_TYPE_PARAMETERS | T_TYPE_PARAMETERS).longValue();
+
+	public static String getTextLabel(Object obj, long flags, Logger logger, JavaUIMessages messages) {
+		if (obj instanceof IJavaElement) {
+			return getElementLabel((IJavaElement) obj, flags, logger, messages);
+		}
+		
+		return "UNKNOWN";
+	}
+	
+	/**
+	 * Returns the label for a Java element with the flags as defined by this class.
+	 *
+	 * @param element the element to render
+	 * @param flags the rendering flags
+	 * @return the label of the Java element
+	 */
+	public static String getElementLabel(IJavaElement element, long flags, Logger logger, JavaUIMessages messages) {
+		StringBuffer result= new StringBuffer();
+		getElementLabel(element, flags, result, logger, messages);
+		return Strings.markJavaElementLabelLTR(result.toString());
+	}
+	
+	/**
+	 * Returns the label for a Java element with the flags as defined by this class.
+	 *
+	 * @param element the element to render
+	 * @param flags the rendering flags
+	 * @param buf the buffer to append the resulting label to
+	 */
+	public static void getElementLabel(IJavaElement element, long flags, StringBuffer buf, Logger logger, JavaUIMessages messages) {
+		new JavaElementLabelComposer(buf,logger,messages).appendElementLabel(element, flags);
+	}
+	
+	/**
+	 * Returns the styled label of the given object. The object must be of type {@link IJavaElement} or adapt to {@link IWorkbenchAdapter}.
+	 * If the element type is not known, the empty string is returned.
+	 * The returned label is BiDi-processed with {@link TextProcessor#process(String, String)}.
+	 *
+	 * @param obj object to get the label for
+	 * @param flags the rendering flags
+	 * @return the label or the empty string if the object type is not supported
+	 *
+	 * @since 3.4
+	 */
+	public static StyledString getStyledTextLabel(Object obj, long flags, Logger logger, JavaUIMessages messages) {
+		if (obj instanceof IJavaElement) {
+			return getStyledElementLabel((IJavaElement) obj, flags, logger, messages);
+		}
+		
+		return new StyledString();
+	}
+	
+	/**
+	 * Returns the styled label for a Java element with the flags as defined by this class.
+	 *
+	 * @param element the element to render
+	 * @param flags the rendering flags
+	 * @return the label of the Java element
+	 *
+	 * @since 3.4
+	 */
+	public static StyledString getStyledElementLabel(IJavaElement element, long flags, Logger logger, JavaUIMessages messages) {
+		StyledString result= new StyledString();
+		getElementLabel(element, flags, result, logger, messages);
+		return Strings.markJavaElementLabelLTR(result);
+	}
+	
+	/**
+	 * Returns the styled label for a Java element with the flags as defined by this class.
+	 *
+	 * @param element the element to render
+	 * @param flags the rendering flags
+	 * @param result the buffer to append the resulting label to
+	 *
+	 * @since 3.4
+	 */
+	public static void getElementLabel(IJavaElement element, long flags, StyledString result, Logger logger, JavaUIMessages messages) {
+		new JavaElementLabelComposer(result, logger, messages).appendElementLabel(element, flags);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaModelUtil.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaModelUtil.java
new file mode 100644
index 0000000..d768f4e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaModelUtil.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Matt Chapman, mpchapman@gmail.com - 89977 Make JDT .java agnostic
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+
+public class JavaModelUtil {
+	/**
+	 * @param type the type to test
+	 * @return <code>true</code> iff the type is an interface or an annotation
+	 * @throws JavaModelException thrown when the field can not be accessed
+	 */
+	public static boolean isInterfaceOrAnnotation(IType type) throws JavaModelException {
+		return type.isInterface();
+	}
+	
+	/**
+	 * Returns the package fragment root of <code>IJavaElement</code>. If the given
+	 * element is already a package fragment root, the element itself is returned.
+	 * @param element the element
+	 * @return the package fragment root of the element or <code>null</code>
+	 */
+	public static IPackageFragmentRoot getPackageFragmentRoot(IJavaElement element) {
+		return (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+	}
+
+	/**
+	 * Returns the classpath entry of the given package fragment root. This is the raw entry, except
+	 * if the root is a referenced library, in which case it's the resolved entry.
+	 * 
+	 * @param root a package fragment root
+	 * @return the corresponding classpath entry
+	 * @throws JavaModelException if accessing the entry failed
+	 * @since 3.6
+	 */
+	public static IClasspathEntry getClasspathEntry(IPackageFragmentRoot root) throws JavaModelException {
+		IClasspathEntry rawEntry= root.getRawClasspathEntry();
+		int rawEntryKind= rawEntry.getEntryKind();
+		switch (rawEntryKind) {
+			case IClasspathEntry.CPE_LIBRARY:
+			case IClasspathEntry.CPE_VARIABLE:
+			case IClasspathEntry.CPE_CONTAINER: // should not happen, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=305037
+				if (root.isArchive() && root.getKind() == IPackageFragmentRoot.K_BINARY) {
+					IClasspathEntry resolvedEntry= root.getResolvedClasspathEntry();
+					if (resolvedEntry.getReferencingEntry() != null)
+						return resolvedEntry;
+					else
+						return rawEntry;
+				}
+		}
+		return rawEntry;
+	}
+	
+	/**
+	 * Checks whether the given type has a valid main method or not.
+	 * @param type the type to test
+	 * @return returns <code>true</code> if the type has a main method
+	 * @throws JavaModelException thrown when the type can not be accessed
+	 */
+	public static boolean hasMainMethod(IType type) throws JavaModelException {
+		IMethod[] methods= type.getMethods();
+		for (int i= 0; i < methods.length; i++) {
+			if (methods[i].isMainMethod()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaPluginImages.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaPluginImages.java
new file mode 100644
index 0000000..5ed8fd1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaPluginImages.java
@@ -0,0 +1,235 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import java.net.URL;
+import java.util.HashMap;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.ImageData;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class JavaPluginImages {
+	public static final IPath ICONS_PATH= new Path("$nl$/icons/full"); //$NON-NLS-1$
+	
+	private static final String T_OBJ= "obj16"; 		//$NON-NLS-1$
+	private static final String T_OVR= "ovr16"; 		//$NON-NLS-1$
+
+	private static final String NAME_PREFIX= "org.eclipse.e4.demo.simpleide.jdt."; //$NON-NLS-1$
+	private static final int    NAME_PREFIX_LENGTH= NAME_PREFIX.length();
+	
+	private static ImageRegistry fgImageRegistry= null;
+	private static HashMap<String,ImageDescriptor> fgAvoidSWTErrorMap= null;
+	public static ImageDescriptorRegistry IMAGE_DESCRIPTOR_REGISTRY = new ImageDescriptorRegistry();
+	
+	public static final String IMG_MISC_PRIVATE= NAME_PREFIX + "methpri_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_OBJS_LOCAL_VARIABLE= NAME_PREFIX + "localvariable_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_PACKDECL= NAME_PREFIX + "packd_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_IMPDECL= NAME_PREFIX + "imp_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_IMPCONT= NAME_PREFIX + "impc_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_EXTJAR= NAME_PREFIX + "jar_l_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_EXTJAR_WSRC= NAME_PREFIX + "jar_lsrc_obj.gif";	//$NON-NLS-1$
+	public static final String IMG_OBJS_JAR= NAME_PREFIX + "jar_obj.gif"; 				//$NON-NLS-1$
+	public static final String IMG_OBJS_JAR_WSRC= NAME_PREFIX + "jar_src_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_OBJS_CLASSFOLDER= NAME_PREFIX + "cf_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_CLASSFOLDER_WSRC= NAME_PREFIX + "cf_src_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_OBJS_PACKFRAG_ROOT= NAME_PREFIX + "packagefolder_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_CUNIT= NAME_PREFIX + "jcu_obj.gif"; 				//$NON-NLS-1$
+	public static final String IMG_OBJS_CFILE= NAME_PREFIX + "classf_obj.gif";  			//$NON-NLS-1$
+	public static final String IMG_OBJS_JAVA_MODEL= NAME_PREFIX + "java_model_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_TYPEVARIABLE= NAME_PREFIX + "typevariable_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_OBJS_ANNOTATION= NAME_PREFIX + "annotation_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_GHOST= NAME_PREFIX + "ghost.gif"; 				//$NON-NLS-1$
+	public static final String IMG_OBJS_UNKNOWN= NAME_PREFIX + "unknown_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_MISC_PUBLIC= NAME_PREFIX + "methpub_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_MISC_PROTECTED= NAME_PREFIX + "methpro_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_MISC_DEFAULT= NAME_PREFIX + "methdef_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_FIELD_PUBLIC= NAME_PREFIX + "field_public_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_FIELD_PROTECTED= NAME_PREFIX + "field_protected_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_FIELD_PRIVATE= NAME_PREFIX + "field_private_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_FIELD_DEFAULT= NAME_PREFIX + "field_default_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_OBJS_EMPTY_PACK_RESOURCE= NAME_PREFIX + "empty_pack_fldr_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_EMPTY_PACKAGE= NAME_PREFIX + "empty_pack_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_PACKAGE= NAME_PREFIX + "package_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_OBJS_ENUM_ALT= NAME_PREFIX + "enum_alt_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_ANNOTATION_ALT= NAME_PREFIX + "annotation_alt_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INTERFACEALT= NAME_PREFIX + "intf_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_CLASSALT= NAME_PREFIX + "classfo_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_ENUM= NAME_PREFIX + "enum_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_ENUM_DEFAULT= NAME_PREFIX + "enum_default_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_ENUM_PROTECTED= NAME_PREFIX + "enum_protected_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_ENUM_PRIVATE= NAME_PREFIX + "enum_private_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_ANNOTATION_DEFAULT= NAME_PREFIX + "annotation_default_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_ANNOTATION_PROTECTED= NAME_PREFIX + "annotation_protected_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_ANNOTATION_PRIVATE= NAME_PREFIX + "annotation_private_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_INTERFACE_PUBLIC= NAME_PREFIX + "innerinterface_public_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_INTERFACE_DEFAULT= NAME_PREFIX + "innerinterface_default_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_INTERFACE_PROTECTED= NAME_PREFIX + "innerinterface_protected_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_INTERFACE_PRIVATE= NAME_PREFIX + "innerinterface_private_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INTERFACE_DEFAULT= NAME_PREFIX + "int_default_obj.gif"; 		//$NON-NLS-1$
+	public static final String IMG_OBJS_INTERFACE= NAME_PREFIX + "int_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_CLASS_PUBLIC= NAME_PREFIX + "innerclass_public_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_CLASS_DEFAULT= NAME_PREFIX + "innerclass_default_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_CLASS_PROTECTED= NAME_PREFIX + "innerclass_protected_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_INNER_CLASS_PRIVATE= NAME_PREFIX + "innerclass_private_obj.gif"; //$NON-NLS-1$
+	public static final String IMG_OBJS_CLASS= NAME_PREFIX + "class_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJS_CLASS_DEFAULT= NAME_PREFIX + "class_default_obj.gif"; 			//$NON-NLS-1$
+	public static final String IMG_OBJ_PROJECT_CLOSED = NAME_PREFIX + "cprj_obj.gif";			//$NON-NLS-1$
+	public static final String IMG_OBJ_PROJECT = NAME_PREFIX + "prj_obj.gif";			//$NON-NLS-1$
+
+	public static final ImageDescriptor DESC_MISC_PRIVATE= createManagedFromKey(T_OBJ, IMG_MISC_PRIVATE);
+	public static final ImageDescriptor DESC_OBJS_LOCAL_VARIABLE= createManagedFromKey(T_OBJ, IMG_OBJS_LOCAL_VARIABLE);
+	public static final ImageDescriptor DESC_OBJS_PACKDECL= createManagedFromKey(T_OBJ, IMG_OBJS_PACKDECL);
+	public static final ImageDescriptor DESC_OBJS_IMPDECL= createManagedFromKey(T_OBJ, IMG_OBJS_IMPDECL);
+	public static final ImageDescriptor DESC_OBJS_IMPCONT= createManagedFromKey(T_OBJ, IMG_OBJS_IMPCONT);
+	public static final ImageDescriptor DESC_OBJS_EXTJAR= createManagedFromKey(T_OBJ, IMG_OBJS_EXTJAR);
+	public static final ImageDescriptor DESC_OBJS_EXTJAR_WSRC= createManagedFromKey(T_OBJ, IMG_OBJS_EXTJAR_WSRC);
+	public static final ImageDescriptor DESC_OBJS_JAR= createManagedFromKey(T_OBJ, IMG_OBJS_JAR);
+	public static final ImageDescriptor DESC_OBJS_JAR_WSRC= createManagedFromKey(T_OBJ, IMG_OBJS_JAR_WSRC);
+	public static final ImageDescriptor DESC_OBJS_CLASSFOLDER= createManagedFromKey(T_OBJ, IMG_OBJS_CLASSFOLDER);
+	public static final ImageDescriptor DESC_OBJS_CLASSFOLDER_WSRC= createManagedFromKey(T_OBJ, IMG_OBJS_CLASSFOLDER_WSRC);
+	public static final ImageDescriptor DESC_OBJS_PACKFRAG_ROOT= createManagedFromKey(T_OBJ, IMG_OBJS_PACKFRAG_ROOT);
+	public static final ImageDescriptor DESC_OBJS_CUNIT= createManagedFromKey(T_OBJ, IMG_OBJS_CUNIT);
+	public static final ImageDescriptor DESC_OBJS_CFILE= createManagedFromKey(T_OBJ, IMG_OBJS_CFILE);
+	public static final ImageDescriptor DESC_OBJS_JAVA_MODEL= createManagedFromKey(T_OBJ, IMG_OBJS_JAVA_MODEL);
+	public static final ImageDescriptor DESC_OBJS_TYPEVARIABLE= createManagedFromKey(T_OBJ, IMG_OBJS_TYPEVARIABLE);
+	public static final ImageDescriptor DESC_OBJS_ANNOTATION= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION);
+	public static final ImageDescriptor DESC_OBJS_GHOST= createManagedFromKey(T_OBJ, IMG_OBJS_GHOST);
+	public static final ImageDescriptor DESC_OBJS_UNKNOWN= createManagedFromKey(T_OBJ, IMG_OBJS_UNKNOWN);
+	public static final ImageDescriptor DESC_MISC_PUBLIC= createManagedFromKey(T_OBJ, IMG_MISC_PUBLIC);
+	public static final ImageDescriptor DESC_MISC_PROTECTED= createManagedFromKey(T_OBJ, IMG_MISC_PROTECTED);
+	public static final ImageDescriptor DESC_MISC_DEFAULT= createManagedFromKey(T_OBJ, IMG_MISC_DEFAULT);
+	public static final ImageDescriptor DESC_FIELD_PUBLIC= createManagedFromKey(T_OBJ, IMG_FIELD_PUBLIC);
+	public static final ImageDescriptor DESC_FIELD_PROTECTED= createManagedFromKey(T_OBJ, IMG_FIELD_PROTECTED);
+	public static final ImageDescriptor DESC_FIELD_PRIVATE= createManagedFromKey(T_OBJ, IMG_FIELD_PRIVATE);
+	public static final ImageDescriptor DESC_FIELD_DEFAULT= createManagedFromKey(T_OBJ, IMG_FIELD_DEFAULT);
+	public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE_RESOURCES= createManagedFromKey(T_OBJ, IMG_OBJS_EMPTY_PACK_RESOURCE);
+	public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE= createManagedFromKey(T_OBJ, IMG_OBJS_EMPTY_PACKAGE);
+	public static final ImageDescriptor DESC_OBJS_PACKAGE= createManagedFromKey(T_OBJ, IMG_OBJS_PACKAGE);
+	public static final ImageDescriptor DESC_OBJS_ENUM_ALT= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_ALT);
+	public static final ImageDescriptor DESC_OBJS_ANNOTATION_ALT= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_ALT);
+	public static final ImageDescriptor DESC_OBJS_INTERFACEALT= createManagedFromKey(T_OBJ, IMG_OBJS_INTERFACEALT);
+	public static final ImageDescriptor DESC_OBJS_CLASSALT= createManagedFromKey(T_OBJ, IMG_OBJS_CLASSALT);
+	public static final ImageDescriptor DESC_OBJS_ENUM= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM);
+	public static final ImageDescriptor DESC_OBJS_ENUM_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_DEFAULT);
+	public static final ImageDescriptor DESC_OBJS_ENUM_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_PROTECTED);
+	public static final ImageDescriptor DESC_OBJS_ENUM_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_PRIVATE);
+	public static final ImageDescriptor DESC_OBJS_ANNOTATION_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_DEFAULT);
+	public static final ImageDescriptor DESC_OBJS_ANNOTATION_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_PROTECTED);
+	public static final ImageDescriptor DESC_OBJS_ANNOTATION_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_PRIVATE);
+	public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PUBLIC= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_PUBLIC);
+	public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_DEFAULT);
+	public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_PROTECTED);
+	public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_PRIVATE);
+	public static final ImageDescriptor DESC_OBJS_INTERFACE_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_INTERFACE_DEFAULT);
+	public static final ImageDescriptor DESC_OBJS_INTERFACE= createManagedFromKey(T_OBJ, IMG_OBJS_INTERFACE);
+	public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PUBLIC= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_PUBLIC);
+	public static final ImageDescriptor DESC_OBJS_INNER_CLASS_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_DEFAULT);
+	public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_PROTECTED);
+	public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_PRIVATE);
+	public static final ImageDescriptor DESC_OBJS_CLASS= createManagedFromKey(T_OBJ, IMG_OBJS_CLASS);
+	public static final ImageDescriptor DESC_OBJS_CLASS_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_CLASS_DEFAULT);
+	public static final ImageDescriptor DESC_OVR_DEPRECATED= createUnManagedCached(T_OVR, "deprecated.gif");			//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_ABSTRACT= createUnManagedCached(T_OVR, "abstract_co.gif"); 					//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_CONSTRUCTOR= createUnManagedCached(T_OVR, "constr_ovr.gif");			//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_FINAL= createUnManagedCached(T_OVR, "final_co.gif"); 						//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_VOLATILE= createUnManagedCached(T_OVR, "volatile_co.gif"); 						//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_STATIC= createUnManagedCached(T_OVR, "static_co.gif"); 						//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_SYNCH_AND_OVERRIDES= createUnManagedCached(T_OVR, "sync_over.gif");  	//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_SYNCH_AND_IMPLEMENTS= createUnManagedCached(T_OVR, "sync_impl.gif");   //$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_OVERRIDES= createUnManagedCached(T_OVR, "over_co.gif");  					//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_IMPLEMENTS= createUnManagedCached(T_OVR, "implm_co.gif");  				//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_SYNCH= createUnManagedCached(T_OVR, "synch_co.gif"); 						//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_RUN= createUnManagedCached(T_OVR, "run_co.gif"); 							//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_TRANSIENT= createUnManagedCached(T_OVR, "transient_co.gif"); 						//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_ERROR= createUnManagedCached(T_OVR, "error_co.gif"); 						//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OVR_WARNING= createUnManagedCached(T_OVR, "warning_co.gif"); 					//$NON-NLS-1$
+	public static final ImageDescriptor DESC_OBJ_PROJECT_CLOSED= createManagedFromKey(T_OBJ, IMG_OBJ_PROJECT_CLOSED);
+	public static final ImageDescriptor DESC_OBJ_PROJECT= createManagedFromKey(T_OBJ, IMG_OBJ_PROJECT);
+	
+	private static final class CachedImageDescriptor extends ImageDescriptor {
+		private ImageDescriptor fDescriptor;
+		private ImageData fData;
+
+		public CachedImageDescriptor(ImageDescriptor descriptor) {
+			fDescriptor = descriptor;
+		}
+
+		public ImageData getImageData() {
+			if (fData == null) {
+				fData= fDescriptor.getImageData();
+			}
+			return fData;
+		}
+	}
+	
+	private static ImageDescriptor createManagedFromKey(String prefix, String key) {
+		return createManaged(prefix, key.substring(NAME_PREFIX_LENGTH), key);
+	}
+	
+	private static ImageDescriptor createManaged(String prefix, String name, String key) {
+		try {
+			ImageDescriptor result= create(prefix, name, true);
+
+			if (fgAvoidSWTErrorMap == null) {
+				fgAvoidSWTErrorMap= new HashMap<String,ImageDescriptor>();
+			}
+			fgAvoidSWTErrorMap.put(key, result);
+			if (fgImageRegistry != null) {
+				
+	//FIXME			JavaPlugin.logErrorMessage("Image registry already defined"); //$NON-NLS-1$
+			}
+			return result;			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return ImageDescriptor.getMissingImageDescriptor();
+	}
+	
+	/*
+	 * Creates an image descriptor for the given prefix and name in the JDT UI bundle. The path can
+	 * contain variables like $NL$.
+	 * If no image could be found, <code>useMissingImageDescriptor</code> decides if either
+	 * the 'missing image descriptor' is returned or <code>null</code>.
+	 * or <code>null</code>.
+	 */
+	private static ImageDescriptor create(String prefix, String name, boolean useMissingImageDescriptor) {
+		IPath path= ICONS_PATH.append(prefix).append(name);
+		return createImageDescriptor(FrameworkUtil.getBundle(JavaPluginImages.class), path, useMissingImageDescriptor);
+	}
+	
+	/*
+	 * Creates an image descriptor for the given path in a bundle. The path can contain variables
+	 * like $NL$.
+	 * If no image could be found, <code>useMissingImageDescriptor</code> decides if either
+	 * the 'missing image descriptor' is returned or <code>null</code>.
+	 * Added for 3.1.1.
+	 */
+	public static ImageDescriptor createImageDescriptor(Bundle bundle, IPath path, boolean useMissingImageDescriptor) {
+		URL url= FileLocator.find(bundle, path, null);
+		if (url != null) {
+			return ImageDescriptor.createFromURL(url);
+		}
+		if (useMissingImageDescriptor) {
+			return ImageDescriptor.getMissingImageDescriptor();
+		}
+		return null;
+	}
+	
+	/*
+	 * Creates an image descriptor for the given prefix and name in the JDT UI bundle and let type descriptor cache the image data.
+	 * If no image could be found, the 'missing image descriptor' is returned.
+	 */
+	private static ImageDescriptor createUnManagedCached(String prefix, String name) {
+		try {
+			return new CachedImageDescriptor(create(prefix, name, true));
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		return ImageDescriptor.getMissingImageDescriptor();
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaUILabelProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaUILabelProvider.java
new file mode 100644
index 0000000..b0dc713
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaUILabelProvider.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.swt.graphics.Image;
+
+public class JavaUILabelProvider extends LabelProvider implements IStyledLabelProvider {
+	private long fTextFlags;
+	private int fImageFlags;
+	
+	private Logger logger;
+	private JavaUIMessages messages;
+	
+	protected JavaElementImageProvider fImageLabelProvider;
+
+	/**
+	 * Creates a new label provider with default flags.
+	 */
+	public JavaUILabelProvider(Logger logger, JavaUIMessages messages) {
+		this(JavaElementLabels.ALL_DEFAULT,JavaElementImageProvider.OVERLAY_ICONS, logger,messages);
+	}
+	
+	public JavaUILabelProvider(long textFlags, int imageFlags, Logger logger, JavaUIMessages messages) {
+		fImageLabelProvider= new JavaElementImageProvider(logger);
+		
+		fTextFlags= textFlags;
+		fImageFlags = imageFlags;
+		this.logger = logger;
+		this.messages = messages;
+	}
+	
+	@Override
+	public String getText(Object element) {
+		String result = JavaElementLabels.getTextLabel(element, evaluateTextFlags(element),logger,messages);
+//		return decorateText(result, element);
+		return result;
+	}
+	
+	public Image getImage(Object element) {
+		Image result= fImageLabelProvider.getImageLabel(element, evaluateImageFlags(element),logger);
+//		return decorateImage(result, element);
+		return result;
+	}
+	
+	/**
+	 * Gets the image flags.
+	 * Can be overwritten by super classes.
+	 * @return Returns a int
+	 */
+	public final int getImageFlags() {
+		return fImageFlags;
+	}
+	
+	/**
+	 * Evaluates the image flags for a element.
+	 * Can be overwritten by super classes.
+	 * @param element the element to compute the image flags for
+	 * @return Returns a int
+	 */
+	protected int evaluateImageFlags(Object element) {
+		return getImageFlags();
+	}
+	
+	/**
+	 * Evaluates the text flags for a element. Can be overwritten by super classes.
+	 * @param element the element to compute the text flags for
+	 * @return Returns a int
+	 */
+	protected long evaluateTextFlags(Object element) {
+		return getTextFlags();
+	}
+	
+	/**
+	 * Gets the text flags.
+	 * @return Returns a int
+	 */
+	public final long getTextFlags() {
+		return fTextFlags;
+	}
+
+	public StyledString getStyledText(Object element) {
+		StyledString string= JavaElementLabels.getStyledTextLabel(element, (evaluateTextFlags(element) | JavaElementLabels.COLORIZE), logger, messages);
+//		System.err.println("Styled string: " + string);
+//		System.err.println(string.getStyleRanges().length);
+		return string;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/Strings.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/Strings.java
new file mode 100644
index 0000000..32ff24f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/Strings.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.osgi.util.TextProcessor;
+
+/**
+ * Helper class to provide String manipulation functions not available in standard JDK.
+ */
+public class Strings {
+	/**
+	 * Tells whether we have to use the {@link TextProcessor}
+	 * <p>
+	 * This is used for performance optimization.
+	 * </p>
+	 * @since 3.4
+	 */
+	public static final boolean USE_TEXT_PROCESSOR;
+	static {
+		String testString= "args : String[]"; //$NON-NLS-1$
+		USE_TEXT_PROCESSOR= testString != TextProcessor.process(testString);
+	}
+	
+	private static final String JAVA_ELEMENT_DELIMITERS= TextProcessor.getDefaultDelimiters() + "<>(),?{} "; //$NON-NLS-1$
+	
+	/**
+	 * Adds special marks so that that the given Java element label is readable in a BiDi
+	 * environment.
+	 * 
+	 * @param string the string
+	 * @return the processed styled string
+	 * @since 3.6
+	 */
+	public static String markJavaElementLabelLTR(String string) {
+		if (!USE_TEXT_PROCESSOR)
+			return string;
+
+		return TextProcessor.process(string, JAVA_ELEMENT_DELIMITERS);
+	}
+	
+	/**
+	 * Adds special marks so that that the given styled Java element label is readable in a BiDi
+	 * environment.
+	 * 
+	 * @param styledString the styled string
+	 * @return the processed styled string
+	 * @since 3.6
+	 */
+	public static StyledString markJavaElementLabelLTR(StyledString styledString) {
+		if (!USE_TEXT_PROCESSOR)
+			return styledString;
+
+		String inputString= styledString.getString();
+		String string= TextProcessor.process(inputString, JAVA_ELEMENT_DELIMITERS);
+		if (string != inputString)
+			insertMarks(styledString, inputString, string);
+		return styledString;
+	}
+
+	/**
+	 * Inserts the marks into the given styled string.
+	 * 
+	 * @param styledString the styled string
+	 * @param originalString the original string
+	 * @param processedString the processed string
+	 * @since 3.5
+	 */
+	private static void insertMarks(StyledString styledString, String originalString, String processedString) {
+		int originalLength= originalString.length();
+		int processedStringLength= processedString.length();
+		char orig= originalLength > 0 ? originalString.charAt(0) : '\0';
+		for (int o= 0, p= 0; p < processedStringLength; p++) {
+			char processed= processedString.charAt(p);
+			if (o < originalLength) {
+				if (orig == processed) {
+					o++;
+					if (o < originalLength)
+						orig= originalString.charAt(o);
+					continue;
+				}
+			}
+			styledString.insert(processed, p);
+		}
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.jdt/xmi/fragment.e4xmi
new file mode 100644
index 0000000..8d312af
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/xmi/fragment.e4xmi
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_37L3wHihEd-1hY0DgxUB9A">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_J1oEEHiiEd-QLpUkCzu7EA" featurename="commands" parentElementId="app.simpleide">
+    <elements xsi:type="commands:Command" xmi:id="_Ov-eMHiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.newclass" commandName="New Java Class"/>
+    <elements xsi:type="commands:Command" xmi:id="_SUdRkHiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.newinterface" commandName="New Java Interface"/>
+    <elements xsi:type="commands:Command" xmi:id="_Uncn4HiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.enum" commandName="New Java Enum"/>
+    <elements xsi:type="commands:Command" xmi:id="_WCXtwHiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.newannotion" commandName="New Java Annotation"/>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_aBkHMHiiEd-QLpUkCzu7EA" featurename="handlers" parentElementId="app.simpleide">
+    <elements xsi:type="commands:Handler" xmi:id="_eKIfEHiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaClassHandler" command="_Ov-eMHiiEd-QLpUkCzu7EA"/>
+    <elements xsi:type="commands:Handler" xmi:id="_hb7nAHiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaInterfaceHandler" command="_SUdRkHiiEd-QLpUkCzu7EA"/>
+    <elements xsi:type="commands:Handler" xmi:id="_jfZTkHiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaEnumHandler" command="_Uncn4HiiEd-QLpUkCzu7EA"/>
+    <elements xsi:type="commands:Handler" xmi:id="_l6VE8HiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaAnnotationHandler" command="_WCXtwHiiEd-QLpUkCzu7EA"/>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_ppKHIHiiEd-QLpUkCzu7EA" featurename="children" parentElementId="simpleide.mainmenu.file.new">
+    <elements xsi:type="menu:HandledMenuItem" xmi:id="_wvvvUHiiEd-QLpUkCzu7EA" label="Class" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif" command="_Ov-eMHiiEd-QLpUkCzu7EA"/>
+    <elements xsi:type="menu:HandledMenuItem" xmi:id="_0eFCQHiiEd-QLpUkCzu7EA" label="Interface" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif" command="_SUdRkHiiEd-QLpUkCzu7EA"/>
+    <elements xsi:type="menu:HandledMenuItem" xmi:id="_4phH8HiiEd-QLpUkCzu7EA" label="Enum" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif" command="_Uncn4HiiEd-QLpUkCzu7EA"/>
+    <elements xsi:type="menu:HandledMenuItem" xmi:id="_7TroIHiiEd-QLpUkCzu7EA" label="Annotation" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif" command="_WCXtwHiiEd-QLpUkCzu7EA"/>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="__FnosHiiEd-QLpUkCzu7EA" featurename="editorPartDescriptors" parentElementId="app.simpleide">
+    <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_EpikQHijEd-QLpUkCzu7EA" label="Java Source Editor" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.internal.editor.JavaEditor">
+      <fileextensions>java</fileextensions>
+    </elements>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.classpath b/examples/org.eclipse.e4.demo.simpleide.model/.classpath
new file mode 100644
index 0000000..304e861
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.project b/examples/org.eclipse.e4.demo.simpleide.model/.project
new file mode 100644
index 0000000..2a72986
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.model</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3d32eef
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Wed Jun 02 15:48:37 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..7a36451
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:08:13 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.model/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9744b28
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.model;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.demo.simpleide.model.simpleide,
+ org.eclipse.e4.demo.simpleide.model.simpleide.impl,
+ org.eclipse.e4.demo.simpleide.model.simpleide.util
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.e4.ui.model.workbench;visibility:=reexport,
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0"
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/build.properties b/examples/org.eclipse.e4.demo.simpleide.model/build.properties
new file mode 100644
index 0000000..66d9c2d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/build.properties
@@ -0,0 +1,14 @@
+
+# <copyright>
+# </copyright>
+#
+# $Id$
+
+bin.includes = .,\
+               model/,\
+               META-INF/,\
+               plugin.xml,\
+               plugin.properties
+jars.compile.order = .
+source.. = src/
+output.. = bin/
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.ecore b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.ecore
new file mode 100644
index 0000000..e742de1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.ecore
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="simpleide"
+    nsURI="http://www.eclipse.org/e4/demo/simpleide" nsPrefix="simpleide">
+  <eClassifiers xsi:type="ecore:EClass" name="SimpleIDEApplication" eSuperTypes="platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//Application">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="editorPartDescriptors"
+        upperBound="-1" eType="#//EditorPartDescriptor" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="EditorPartDescriptor" eSuperTypes="platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//ApplicationElement platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//ui/UILabel platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//commands/HandlerContainer platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//commands/Bindings">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="contributionURI" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="fileextensions" upperBound="-1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="contenttypes" upperBound="-1"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.genmodel b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.genmodel
new file mode 100644
index 0000000..30f7de0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.genmodel
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+    xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.e4.demo.simpleide.model/src"
+    modelPluginID="org.eclipse.e4.demo.simpleide.model" modelName="SimpleIDE" rootExtendsInterface=""
+    rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl.Container" suppressEMFTypes="true"
+    suppressEMFMetaData="true" importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0"
+    copyrightFields="false" usedGenPackages="platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.genmodel#//application"
+    interfaceNamePattern="M{0}">
+  <foreignModel>SimpleIDE.ecore</foreignModel>
+  <genPackages prefix="Simpleide" basePackage="org.eclipse.e4.demo.simpleide.model"
+      disposableProviderFactory="true" ecorePackage="SimpleIDE.ecore#/">
+    <genClasses ecoreClass="SimpleIDE.ecore#//SimpleIDEApplication">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference SimpleIDE.ecore#//SimpleIDEApplication/editorPartDescriptors"/>
+    </genClasses>
+    <genClasses ecoreClass="SimpleIDE.ecore#//EditorPartDescriptor">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SimpleIDE.ecore#//EditorPartDescriptor/contributionURI"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SimpleIDE.ecore#//EditorPartDescriptor/fileextensions"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SimpleIDE.ecore#//EditorPartDescriptor/contenttypes"/>
+    </genClasses>
+  </genPackages>
+</genmodel:GenModel>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/plugin.properties b/examples/org.eclipse.e4.demo.simpleide.model/plugin.properties
new file mode 100644
index 0000000..522321c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/plugin.properties
@@ -0,0 +1,8 @@
+
+# <copyright>
+# </copyright>
+#
+# $Id$
+
+pluginName = SimpleIDE Model
+providerName = www.example.org
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.model/plugin.xml
new file mode 100644
index 0000000..14e79e8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<!--
+ <copyright>
+ </copyright>
+
+ $Id$
+-->
+
+<plugin>
+
+   <extension point="org.eclipse.emf.ecore.generated_package">
+      <package
+            uri="http://www.eclipse.org/e4/demo/simpleide"
+            class="org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl"
+            genModel="model/SimpleIDE.genmodel"/>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MEditorPartDescriptor.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MEditorPartDescriptor.java
new file mode 100644
index 0000000..afa7e71
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MEditorPartDescriptor.java
@@ -0,0 +1,88 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: MEditorPartDescriptor.java,v 1.3 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide;
+
+import java.util.List;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Editor Part Descriptor</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI <em>Contribution URI</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getFileextensions <em>Fileextensions</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContenttypes <em>Contenttypes</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @model
+ * @generated
+ */
+public interface MEditorPartDescriptor extends MApplicationElement, MUILabel, MHandlerContainer, MBindings {
+	/**
+	 * Returns the value of the '<em><b>Contribution URI</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Contribution URI</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Contribution URI</em>' attribute.
+	 * @see #setContributionURI(String)
+	 * @model
+	 * @generated
+	 */
+	String getContributionURI();
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI <em>Contribution URI</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Contribution URI</em>' attribute.
+	 * @see #getContributionURI()
+	 * @generated
+	 */
+	void setContributionURI(String value);
+
+	/**
+	 * Returns the value of the '<em><b>Fileextensions</b></em>' attribute list.
+	 * The list contents are of type {@link java.lang.String}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Fileextensions</em>' attribute list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Fileextensions</em>' attribute list.
+	 * @model
+	 * @generated
+	 */
+	List<String> getFileextensions();
+
+	/**
+	 * Returns the value of the '<em><b>Contenttypes</b></em>' attribute list.
+	 * The list contents are of type {@link java.lang.String}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Contenttypes</em>' attribute list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Contenttypes</em>' attribute list.
+	 * @model
+	 * @generated
+	 */
+	List<String> getContenttypes();
+
+} // MEditorPartDescriptor
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleIDEApplication.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleIDEApplication.java
new file mode 100644
index 0000000..3cae580
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleIDEApplication.java
@@ -0,0 +1,43 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: MSimpleIDEApplication.java,v 1.1 2010/05/15 12:59:52 tschindl Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide;
+
+import java.util.List;
+import org.eclipse.e4.ui.model.application.MApplication;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Simple IDE Application</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication#getEditorPartDescriptors <em>Editor Part Descriptors</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @model
+ * @generated
+ */
+public interface MSimpleIDEApplication extends MApplication {
+	/**
+	 * Returns the value of the '<em><b>Editor Part Descriptors</b></em>' containment reference list.
+	 * The list contents are of type {@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Editor Part Descriptors</em>' containment reference list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Editor Part Descriptors</em>' containment reference list.
+	 * @model containment="true"
+	 * @generated
+	 */
+	List<MEditorPartDescriptor> getEditorPartDescriptors();
+
+} // MSimpleIDEApplication
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleideFactory.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleideFactory.java
new file mode 100644
index 0000000..0310c2e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleideFactory.java
@@ -0,0 +1,44 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide;
+
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Factory</b> for the model.
+ * It provides a create method for each non-abstract class of the model.
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public interface MSimpleideFactory {
+	/**
+	 * The singleton instance of the factory.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	MSimpleideFactory INSTANCE = org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleideFactoryImpl.eINSTANCE;
+
+	/**
+	 * Returns a new object of class '<em>Simple IDE Application</em>'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return a new object of class '<em>Simple IDE Application</em>'.
+	 * @generated
+	 */
+	MSimpleIDEApplication createSimpleIDEApplication();
+
+	/**
+	 * Returns a new object of class '<em>Editor Part Descriptor</em>'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return a new object of class '<em>Editor Part Descriptor</em>'.
+	 * @generated
+	 */
+	MEditorPartDescriptor createEditorPartDescriptor();
+
+} //MSimpleideFactory
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/EditorPartDescriptorImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/EditorPartDescriptorImpl.java
new file mode 100644
index 0000000..eb02589
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/EditorPartDescriptorImpl.java
@@ -0,0 +1,581 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: EditorPartDescriptorImpl.java,v 1.5 2011/01/17 12:18:07 pwebster Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import java.util.Collection;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.ui.model.application.commands.MBindingContext;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandler;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationElementImpl;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.EObjectResolvingEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Editor Part Descriptor</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getLabel <em>Label</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getIconURI <em>Icon URI</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getTooltip <em>Tooltip</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getHandlers <em>Handlers</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getBindingContexts <em>Binding Contexts</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getContributionURI <em>Contribution URI</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getFileextensions <em>Fileextensions</em>}</li>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getContenttypes <em>Contenttypes</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+public class EditorPartDescriptorImpl extends ApplicationElementImpl implements MEditorPartDescriptor {
+	/**
+	 * The default value of the '{@link #getLabel() <em>Label</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getLabel()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String LABEL_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getLabel() <em>Label</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getLabel()
+	 * @generated
+	 * @ordered
+	 */
+	protected String label = LABEL_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getIconURI() <em>Icon URI</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getIconURI()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String ICON_URI_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getIconURI() <em>Icon URI</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getIconURI()
+	 * @generated
+	 * @ordered
+	 */
+	protected String iconURI = ICON_URI_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getTooltip() <em>Tooltip</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getTooltip()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String TOOLTIP_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getTooltip() <em>Tooltip</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getTooltip()
+	 * @generated
+	 * @ordered
+	 */
+	protected String tooltip = TOOLTIP_EDEFAULT;
+
+	/**
+	 * The cached value of the '{@link #getHandlers() <em>Handlers</em>}' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getHandlers()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<MHandler> handlers;
+
+	/**
+	 * The cached value of the '{@link #getBindingContexts() <em>Binding Contexts</em>}' reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getBindingContexts()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<MBindingContext> bindingContexts;
+
+	/**
+	 * The default value of the '{@link #getContributionURI() <em>Contribution URI</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getContributionURI()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String CONTRIBUTION_URI_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getContributionURI() <em>Contribution URI</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getContributionURI()
+	 * @generated
+	 * @ordered
+	 */
+	protected String contributionURI = CONTRIBUTION_URI_EDEFAULT;
+
+	/**
+	 * The cached value of the '{@link #getFileextensions() <em>Fileextensions</em>}' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getFileextensions()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<String> fileextensions;
+
+	/**
+	 * The cached value of the '{@link #getContenttypes() <em>Contenttypes</em>}' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getContenttypes()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<String> contenttypes;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected EditorPartDescriptorImpl() {
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass() {
+		return SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getLabel() {
+		return label;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setLabel(String newLabel) {
+		String oldLabel = label;
+		label = newLabel;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL, oldLabel, label));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getIconURI() {
+		return iconURI;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setIconURI(String newIconURI) {
+		String oldIconURI = iconURI;
+		iconURI = newIconURI;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI, oldIconURI, iconURI));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getTooltip() {
+		return tooltip;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setTooltip(String newTooltip) {
+		String oldTooltip = tooltip;
+		tooltip = newTooltip;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP, oldTooltip, tooltip));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public List<MHandler> getHandlers() {
+		if (handlers == null) {
+			handlers = new EObjectContainmentEList<MHandler>(MHandler.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS);
+		}
+		return handlers;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public List<MBindingContext> getBindingContexts() {
+		if (bindingContexts == null) {
+			bindingContexts = new EObjectResolvingEList<MBindingContext>(MBindingContext.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS);
+		}
+		return bindingContexts;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getContributionURI() {
+		return contributionURI;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setContributionURI(String newContributionURI) {
+		String oldContributionURI = contributionURI;
+		contributionURI = newContributionURI;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI, oldContributionURI, contributionURI));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public List<String> getFileextensions() {
+		if (fileextensions == null) {
+			fileextensions = new EDataTypeUniqueEList<String>(String.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS);
+		}
+		return fileextensions;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public List<String> getContenttypes() {
+		if (contenttypes == null) {
+			contenttypes = new EDataTypeUniqueEList<String>(String.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES);
+		}
+		return contenttypes;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getLocalizedLabel() {
+		// TODO: implement this method
+		// Ensure that you remove @generated or mark it @generated NOT
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getLocalizedTooltip() {
+		// TODO: implement this method
+		// Ensure that you remove @generated or mark it @generated NOT
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+		switch (featureID) {
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+				return ((InternalEList<?>)getHandlers()).basicRemove(otherEnd, msgs);
+		}
+		return super.eInverseRemove(otherEnd, featureID, msgs);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType) {
+		switch (featureID) {
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+				return getLabel();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+				return getIconURI();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+				return getTooltip();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+				return getHandlers();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+				return getBindingContexts();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+				return getContributionURI();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+				return getFileextensions();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+				return getContenttypes();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void eSet(int featureID, Object newValue) {
+		switch (featureID) {
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+				setLabel((String)newValue);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+				setIconURI((String)newValue);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+				setTooltip((String)newValue);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+				getHandlers().clear();
+				getHandlers().addAll((Collection<? extends MHandler>)newValue);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+				getBindingContexts().clear();
+				getBindingContexts().addAll((Collection<? extends MBindingContext>)newValue);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+				setContributionURI((String)newValue);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+				getFileextensions().clear();
+				getFileextensions().addAll((Collection<? extends String>)newValue);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+				getContenttypes().clear();
+				getContenttypes().addAll((Collection<? extends String>)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID) {
+		switch (featureID) {
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+				setLabel(LABEL_EDEFAULT);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+				setIconURI(ICON_URI_EDEFAULT);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+				setTooltip(TOOLTIP_EDEFAULT);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+				getHandlers().clear();
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+				getBindingContexts().clear();
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+				setContributionURI(CONTRIBUTION_URI_EDEFAULT);
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+				getFileextensions().clear();
+				return;
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+				getContenttypes().clear();
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID) {
+		switch (featureID) {
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+				return LABEL_EDEFAULT == null ? label != null : !LABEL_EDEFAULT.equals(label);
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+				return ICON_URI_EDEFAULT == null ? iconURI != null : !ICON_URI_EDEFAULT.equals(iconURI);
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+				return TOOLTIP_EDEFAULT == null ? tooltip != null : !TOOLTIP_EDEFAULT.equals(tooltip);
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+				return handlers != null && !handlers.isEmpty();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+				return bindingContexts != null && !bindingContexts.isEmpty();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+				return CONTRIBUTION_URI_EDEFAULT == null ? contributionURI != null : !CONTRIBUTION_URI_EDEFAULT.equals(contributionURI);
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+				return fileextensions != null && !fileextensions.isEmpty();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+				return contenttypes != null && !contenttypes.isEmpty();
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
+		if (baseClass == MUILabel.class) {
+			switch (derivedFeatureID) {
+				case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL: return UiPackageImpl.UI_LABEL__LABEL;
+				case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI: return UiPackageImpl.UI_LABEL__ICON_URI;
+				case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP: return UiPackageImpl.UI_LABEL__TOOLTIP;
+				default: return -1;
+			}
+		}
+		if (baseClass == MHandlerContainer.class) {
+			switch (derivedFeatureID) {
+				case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS: return CommandsPackageImpl.HANDLER_CONTAINER__HANDLERS;
+				default: return -1;
+			}
+		}
+		if (baseClass == MBindings.class) {
+			switch (derivedFeatureID) {
+				case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS: return CommandsPackageImpl.BINDINGS__BINDING_CONTEXTS;
+				default: return -1;
+			}
+		}
+		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
+		if (baseClass == MUILabel.class) {
+			switch (baseFeatureID) {
+				case UiPackageImpl.UI_LABEL__LABEL: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL;
+				case UiPackageImpl.UI_LABEL__ICON_URI: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI;
+				case UiPackageImpl.UI_LABEL__TOOLTIP: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP;
+				default: return -1;
+			}
+		}
+		if (baseClass == MHandlerContainer.class) {
+			switch (baseFeatureID) {
+				case CommandsPackageImpl.HANDLER_CONTAINER__HANDLERS: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS;
+				default: return -1;
+			}
+		}
+		if (baseClass == MBindings.class) {
+			switch (baseFeatureID) {
+				case CommandsPackageImpl.BINDINGS__BINDING_CONTEXTS: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS;
+				default: return -1;
+			}
+		}
+		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString() {
+		if (eIsProxy()) return super.toString();
+
+		StringBuffer result = new StringBuffer(super.toString());
+		result.append(" (label: ");
+		result.append(label);
+		result.append(", iconURI: ");
+		result.append(iconURI);
+		result.append(", tooltip: ");
+		result.append(tooltip);
+		result.append(", contributionURI: ");
+		result.append(contributionURI);
+		result.append(", fileextensions: ");
+		result.append(fileextensions);
+		result.append(", contenttypes: ");
+		result.append(contenttypes);
+		result.append(')');
+		return result.toString();
+	}
+
+} //EditorPartDescriptorImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleIDEApplicationImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleIDEApplicationImpl.java
new file mode 100644
index 0000000..663393a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleIDEApplicationImpl.java
@@ -0,0 +1,150 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleIDEApplicationImpl.java,v 1.1 2010/05/15 12:59:52 tschindl Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import java.util.Collection;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.ui.model.application.impl.ApplicationImpl;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Simple IDE Application</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ *   <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl#getEditorPartDescriptors <em>Editor Part Descriptors</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+public class SimpleIDEApplicationImpl extends ApplicationImpl implements MSimpleIDEApplication {
+	/**
+	 * The cached value of the '{@link #getEditorPartDescriptors() <em>Editor Part Descriptors</em>}' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getEditorPartDescriptors()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<MEditorPartDescriptor> editorPartDescriptors;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected SimpleIDEApplicationImpl() {
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass() {
+		return SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public List<MEditorPartDescriptor> getEditorPartDescriptors() {
+		if (editorPartDescriptors == null) {
+			editorPartDescriptors = new EObjectContainmentEList<MEditorPartDescriptor>(MEditorPartDescriptor.class, this, SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS);
+		}
+		return editorPartDescriptors;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+		switch (featureID) {
+			case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+				return ((InternalEList<?>)getEditorPartDescriptors()).basicRemove(otherEnd, msgs);
+		}
+		return super.eInverseRemove(otherEnd, featureID, msgs);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType) {
+		switch (featureID) {
+			case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+				return getEditorPartDescriptors();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public void eSet(int featureID, Object newValue) {
+		switch (featureID) {
+			case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+				getEditorPartDescriptors().clear();
+				getEditorPartDescriptors().addAll((Collection<? extends MEditorPartDescriptor>)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID) {
+		switch (featureID) {
+			case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+				getEditorPartDescriptors().clear();
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID) {
+		switch (featureID) {
+			case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+				return editorPartDescriptors != null && !editorPartDescriptors.isEmpty();
+		}
+		return super.eIsSet(featureID);
+	}
+
+} //SimpleIDEApplicationImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleideFactoryImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleideFactoryImpl.java
new file mode 100644
index 0000000..d97dc5a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleideFactoryImpl.java
@@ -0,0 +1,118 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleideFactoryImpl.java,v 1.2 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.*;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.impl.EFactoryImpl;
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Factory</b>.
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public class SimpleideFactoryImpl extends EFactoryImpl implements MSimpleideFactory {
+	/**
+	 * The singleton instance of the factory.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final SimpleideFactoryImpl eINSTANCE = init();
+
+	/**
+	 * Creates the default factory implementation.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static SimpleideFactoryImpl init() {
+		try {
+			SimpleideFactoryImpl theSimpleideFactory = (SimpleideFactoryImpl)EPackage.Registry.INSTANCE.getEFactory("http://www.eclipse.org/e4/demo/simpleide"); 
+			if (theSimpleideFactory != null) {
+				return theSimpleideFactory;
+			}
+		}
+		catch (Exception exception) {
+			EcorePlugin.INSTANCE.log(exception);
+		}
+		return new SimpleideFactoryImpl();
+	}
+
+	/**
+	 * Creates an instance of the factory.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public SimpleideFactoryImpl() {
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public EObject create(EClass eClass) {
+		switch (eClass.getClassifierID()) {
+			case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION: return (EObject)createSimpleIDEApplication();
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR: return (EObject)createEditorPartDescriptor();
+			default:
+				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
+		}
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public MSimpleIDEApplication createSimpleIDEApplication() {
+		SimpleIDEApplicationImpl simpleIDEApplication = new SimpleIDEApplicationImpl();
+		return simpleIDEApplication;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public MEditorPartDescriptor createEditorPartDescriptor() {
+		EditorPartDescriptorImpl editorPartDescriptor = new EditorPartDescriptorImpl();
+		return editorPartDescriptor;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public SimpleidePackageImpl getSimpleidePackage() {
+		return (SimpleidePackageImpl)getEPackage();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @deprecated
+	 * @generated
+	 */
+	@Deprecated
+	public static SimpleidePackageImpl getPackage() {
+		return SimpleidePackageImpl.eINSTANCE;
+	}
+
+} //SimpleideFactoryImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleidePackageImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleidePackageImpl.java
new file mode 100644
index 0000000..fe656d3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleidePackageImpl.java
@@ -0,0 +1,791 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleidePackageImpl.java,v 1.6 2011/01/17 12:18:07 pwebster Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Package</b> for the model.
+ * It contains accessors for the meta objects to represent
+ * <ul>
+ *   <li>each class,</li>
+ *   <li>each feature of each class,</li>
+ *   <li>each enum,</li>
+ *   <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory
+ * @model kind="package"
+ * @generated
+ */
+public class SimpleidePackageImpl extends EPackageImpl {
+	/**
+	 * The package name.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final String eNAME = "simpleide";
+
+	/**
+	 * The package namespace URI.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final String eNS_URI = "http://www.eclipse.org/e4/demo/simpleide";
+
+	/**
+	 * The package namespace name.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final String eNS_PREFIX = "simpleide";
+
+	/**
+	 * The singleton instance of the package.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public static final SimpleidePackageImpl eINSTANCE = org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl.init();
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl <em>Simple IDE Application</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getSimpleIDEApplication()
+	 * @generated
+	 */
+	public static final int SIMPLE_IDE_APPLICATION = 0;
+
+	/**
+	 * The feature id for the '<em><b>Element Id</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__ELEMENT_ID = ApplicationPackageImpl.APPLICATION__ELEMENT_ID;
+
+	/**
+	 * The feature id for the '<em><b>Tags</b></em>' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__TAGS = ApplicationPackageImpl.APPLICATION__TAGS;
+
+	/**
+	 * The feature id for the '<em><b>Contributor URI</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__CONTRIBUTOR_URI = ApplicationPackageImpl.APPLICATION__CONTRIBUTOR_URI;
+
+	/**
+	 * The feature id for the '<em><b>Widget</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__WIDGET = ApplicationPackageImpl.APPLICATION__WIDGET;
+
+	/**
+	 * The feature id for the '<em><b>Renderer</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__RENDERER = ApplicationPackageImpl.APPLICATION__RENDERER;
+
+	/**
+	 * The feature id for the '<em><b>To Be Rendered</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__TO_BE_RENDERED = ApplicationPackageImpl.APPLICATION__TO_BE_RENDERED;
+
+	/**
+	 * The feature id for the '<em><b>On Top</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__ON_TOP = ApplicationPackageImpl.APPLICATION__ON_TOP;
+
+	/**
+	 * The feature id for the '<em><b>Visible</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__VISIBLE = ApplicationPackageImpl.APPLICATION__VISIBLE;
+
+	/**
+	 * The feature id for the '<em><b>Parent</b></em>' container reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__PARENT = ApplicationPackageImpl.APPLICATION__PARENT;
+
+	/**
+	 * The feature id for the '<em><b>Container Data</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__CONTAINER_DATA = ApplicationPackageImpl.APPLICATION__CONTAINER_DATA;
+
+	/**
+	 * The feature id for the '<em><b>Cur Shared Ref</b></em>' reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__CUR_SHARED_REF = ApplicationPackageImpl.APPLICATION__CUR_SHARED_REF;
+
+	/**
+	 * The feature id for the '<em><b>Visible When</b></em>' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__VISIBLE_WHEN = ApplicationPackageImpl.APPLICATION__VISIBLE_WHEN;
+
+	/**
+	 * The feature id for the '<em><b>Accessibility Phrase</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__ACCESSIBILITY_PHRASE = ApplicationPackageImpl.APPLICATION__ACCESSIBILITY_PHRASE;
+
+	/**
+	 * The feature id for the '<em><b>Children</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__CHILDREN = ApplicationPackageImpl.APPLICATION__CHILDREN;
+
+	/**
+	 * The feature id for the '<em><b>Selected Element</b></em>' reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__SELECTED_ELEMENT = ApplicationPackageImpl.APPLICATION__SELECTED_ELEMENT;
+
+	/**
+	 * The feature id for the '<em><b>Context</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__CONTEXT = ApplicationPackageImpl.APPLICATION__CONTEXT;
+
+	/**
+	 * The feature id for the '<em><b>Variables</b></em>' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__VARIABLES = ApplicationPackageImpl.APPLICATION__VARIABLES;
+
+	/**
+	 * The feature id for the '<em><b>Properties</b></em>' map.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__PROPERTIES = ApplicationPackageImpl.APPLICATION__PROPERTIES;
+
+	/**
+	 * The feature id for the '<em><b>Handlers</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__HANDLERS = ApplicationPackageImpl.APPLICATION__HANDLERS;
+
+	/**
+	 * The feature id for the '<em><b>Binding Tables</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__BINDING_TABLES = ApplicationPackageImpl.APPLICATION__BINDING_TABLES;
+
+	/**
+	 * The feature id for the '<em><b>Root Context</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__ROOT_CONTEXT = ApplicationPackageImpl.APPLICATION__ROOT_CONTEXT;
+
+	/**
+	 * The feature id for the '<em><b>Descriptors</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__DESCRIPTORS = ApplicationPackageImpl.APPLICATION__DESCRIPTORS;
+
+	/**
+	 * The feature id for the '<em><b>Binding Contexts</b></em>' reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__BINDING_CONTEXTS = ApplicationPackageImpl.APPLICATION__BINDING_CONTEXTS;
+
+	/**
+	 * The feature id for the '<em><b>Menu Contributions</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__MENU_CONTRIBUTIONS = ApplicationPackageImpl.APPLICATION__MENU_CONTRIBUTIONS;
+
+	/**
+	 * The feature id for the '<em><b>Tool Bar Contributions</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__TOOL_BAR_CONTRIBUTIONS = ApplicationPackageImpl.APPLICATION__TOOL_BAR_CONTRIBUTIONS;
+
+	/**
+	 * The feature id for the '<em><b>Trim Contributions</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__TRIM_CONTRIBUTIONS = ApplicationPackageImpl.APPLICATION__TRIM_CONTRIBUTIONS;
+
+	/**
+	 * The feature id for the '<em><b>Commands</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__COMMANDS = ApplicationPackageImpl.APPLICATION__COMMANDS;
+
+	/**
+	 * The feature id for the '<em><b>Addons</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__ADDONS = ApplicationPackageImpl.APPLICATION__ADDONS;
+
+	/**
+	 * The feature id for the '<em><b>Categories</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__CATEGORIES = ApplicationPackageImpl.APPLICATION__CATEGORIES;
+
+	/**
+	 * The feature id for the '<em><b>Editor Part Descriptors</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS = ApplicationPackageImpl.APPLICATION_FEATURE_COUNT + 0;
+
+	/**
+	 * The number of structural features of the '<em>Simple IDE Application</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SIMPLE_IDE_APPLICATION_FEATURE_COUNT = ApplicationPackageImpl.APPLICATION_FEATURE_COUNT + 1;
+
+	/**
+	 * The meta object id for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl <em>Editor Part Descriptor</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getEditorPartDescriptor()
+	 * @generated
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR = 1;
+
+	/**
+	 * The feature id for the '<em><b>Element Id</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__ELEMENT_ID = ApplicationPackageImpl.APPLICATION_ELEMENT__ELEMENT_ID;
+
+	/**
+	 * The feature id for the '<em><b>Tags</b></em>' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__TAGS = ApplicationPackageImpl.APPLICATION_ELEMENT__TAGS;
+
+	/**
+	 * The feature id for the '<em><b>Contributor URI</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__CONTRIBUTOR_URI = ApplicationPackageImpl.APPLICATION_ELEMENT__CONTRIBUTOR_URI;
+
+	/**
+	 * The feature id for the '<em><b>Label</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__LABEL = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 0;
+
+	/**
+	 * The feature id for the '<em><b>Icon URI</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__ICON_URI = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 1;
+
+	/**
+	 * The feature id for the '<em><b>Tooltip</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__TOOLTIP = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 2;
+
+	/**
+	 * The feature id for the '<em><b>Handlers</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__HANDLERS = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 3;
+
+	/**
+	 * The feature id for the '<em><b>Binding Contexts</b></em>' reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 4;
+
+	/**
+	 * The feature id for the '<em><b>Contribution URI</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 5;
+
+	/**
+	 * The feature id for the '<em><b>Fileextensions</b></em>' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 6;
+
+	/**
+	 * The feature id for the '<em><b>Contenttypes</b></em>' attribute list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR__CONTENTTYPES = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 7;
+
+	/**
+	 * The number of structural features of the '<em>Editor Part Descriptor</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int EDITOR_PART_DESCRIPTOR_FEATURE_COUNT = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 8;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass simpleIDEApplicationEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass editorPartDescriptorEClass = null;
+
+	/**
+	 * Creates an instance of the model <b>Package</b>, registered with
+	 * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
+	 * package URI value.
+	 * <p>Note: the correct way to create the package is via the static
+	 * factory method {@link #init init()}, which also performs
+	 * initialization of the package, or returns the registered package,
+	 * if one already exists.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.emf.ecore.EPackage.Registry
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#eNS_URI
+	 * @see #init()
+	 * @generated
+	 */
+	private SimpleidePackageImpl() {
+		super(eNS_URI, ((EFactory)MSimpleideFactory.INSTANCE));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private static boolean isInited = false;
+
+	/**
+	 * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
+	 * 
+	 * <p>This method is used to initialize {@link SimpleidePackageImpl#eINSTANCE} when that field is accessed.
+	 * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #eNS_URI
+	 * @see #createPackageContents()
+	 * @see #initializePackageContents()
+	 * @generated
+	 */
+	public static SimpleidePackageImpl init() {
+		if (isInited) return (SimpleidePackageImpl)EPackage.Registry.INSTANCE.getEPackage(SimpleidePackageImpl.eNS_URI);
+
+		// Obtain or create and register package
+		SimpleidePackageImpl theSimpleidePackage = (SimpleidePackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof SimpleidePackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new SimpleidePackageImpl());
+
+		isInited = true;
+
+		// Initialize simple dependencies
+		ApplicationPackageImpl.eINSTANCE.eClass();
+
+		// Create package meta-data objects
+		theSimpleidePackage.createPackageContents();
+
+		// Initialize created meta-data
+		theSimpleidePackage.initializePackageContents();
+
+		// Mark meta-data to indicate it can't be changed
+		theSimpleidePackage.freeze();
+
+  
+		// Update the registry and return the package
+		EPackage.Registry.INSTANCE.put(SimpleidePackageImpl.eNS_URI, theSimpleidePackage);
+		return theSimpleidePackage;
+	}
+
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication <em>Simple IDE Application</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Simple IDE Application</em>'.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication
+	 * @generated
+	 */
+	public EClass getSimpleIDEApplication() {
+		return simpleIDEApplicationEClass;
+	}
+
+	/**
+	 * Returns the meta object for the containment reference list '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication#getEditorPartDescriptors <em>Editor Part Descriptors</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the containment reference list '<em>Editor Part Descriptors</em>'.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication#getEditorPartDescriptors()
+	 * @see #getSimpleIDEApplication()
+	 * @generated
+	 */
+	public EReference getSimpleIDEApplication_EditorPartDescriptors() {
+		return (EReference)simpleIDEApplicationEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor <em>Editor Part Descriptor</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Editor Part Descriptor</em>'.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor
+	 * @generated
+	 */
+	public EClass getEditorPartDescriptor() {
+		return editorPartDescriptorEClass;
+	}
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI <em>Contribution URI</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Contribution URI</em>'.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI()
+	 * @see #getEditorPartDescriptor()
+	 * @generated
+	 */
+	public EAttribute getEditorPartDescriptor_ContributionURI() {
+		return (EAttribute)editorPartDescriptorEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * Returns the meta object for the attribute list '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getFileextensions <em>Fileextensions</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute list '<em>Fileextensions</em>'.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getFileextensions()
+	 * @see #getEditorPartDescriptor()
+	 * @generated
+	 */
+	public EAttribute getEditorPartDescriptor_Fileextensions() {
+		return (EAttribute)editorPartDescriptorEClass.getEStructuralFeatures().get(1);
+	}
+
+	/**
+	 * Returns the meta object for the attribute list '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContenttypes <em>Contenttypes</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute list '<em>Contenttypes</em>'.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContenttypes()
+	 * @see #getEditorPartDescriptor()
+	 * @generated
+	 */
+	public EAttribute getEditorPartDescriptor_Contenttypes() {
+		return (EAttribute)editorPartDescriptorEClass.getEStructuralFeatures().get(2);
+	}
+
+
+	/**
+	 * Returns the factory that creates the instances of the model.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the factory that creates the instances of the model.
+	 * @generated
+	 */
+	public MSimpleideFactory getSimpleideFactory() {
+		return (MSimpleideFactory)getEFactoryInstance();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private boolean isCreated = false;
+
+	/**
+	 * Creates the meta-model objects for the package.  This method is
+	 * guarded to have no affect on any invocation but its first.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void createPackageContents() {
+		if (isCreated) return;
+		isCreated = true;
+
+		// Create classes and their features
+		simpleIDEApplicationEClass = createEClass(SIMPLE_IDE_APPLICATION);
+		createEReference(simpleIDEApplicationEClass, SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS);
+
+		editorPartDescriptorEClass = createEClass(EDITOR_PART_DESCRIPTOR);
+		createEAttribute(editorPartDescriptorEClass, EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI);
+		createEAttribute(editorPartDescriptorEClass, EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS);
+		createEAttribute(editorPartDescriptorEClass, EDITOR_PART_DESCRIPTOR__CONTENTTYPES);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private boolean isInitialized = false;
+
+	/**
+	 * Complete the initialization of the package and its meta-model.  This
+	 * method is guarded to have no affect on any invocation but its first.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void initializePackageContents() {
+		if (isInitialized) return;
+		isInitialized = true;
+
+		// Initialize package
+		setName(eNAME);
+		setNsPrefix(eNS_PREFIX);
+		setNsURI(eNS_URI);
+
+		// Obtain other dependent packages
+		ApplicationPackageImpl theApplicationPackage = (ApplicationPackageImpl)EPackage.Registry.INSTANCE.getEPackage(ApplicationPackageImpl.eNS_URI);
+		UiPackageImpl theUiPackage = (UiPackageImpl)EPackage.Registry.INSTANCE.getEPackage(UiPackageImpl.eNS_URI);
+		CommandsPackageImpl theCommandsPackage = (CommandsPackageImpl)EPackage.Registry.INSTANCE.getEPackage(CommandsPackageImpl.eNS_URI);
+
+		// Create type parameters
+
+		// Set bounds for type parameters
+
+		// Add supertypes to classes
+		simpleIDEApplicationEClass.getESuperTypes().add(theApplicationPackage.getApplication());
+		editorPartDescriptorEClass.getESuperTypes().add(theApplicationPackage.getApplicationElement());
+		editorPartDescriptorEClass.getESuperTypes().add(theUiPackage.getUILabel());
+		editorPartDescriptorEClass.getESuperTypes().add(theCommandsPackage.getHandlerContainer());
+		editorPartDescriptorEClass.getESuperTypes().add(theCommandsPackage.getBindings());
+
+		// Initialize classes and features; add operations and parameters
+		initEClass(simpleIDEApplicationEClass, MSimpleIDEApplication.class, "SimpleIDEApplication", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEReference(getSimpleIDEApplication_EditorPartDescriptors(), this.getEditorPartDescriptor(), null, "editorPartDescriptors", null, 0, -1, MSimpleIDEApplication.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+		initEClass(editorPartDescriptorEClass, MEditorPartDescriptor.class, "EditorPartDescriptor", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEAttribute(getEditorPartDescriptor_ContributionURI(), ecorePackage.getEString(), "contributionURI", null, 0, 1, MEditorPartDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getEditorPartDescriptor_Fileextensions(), ecorePackage.getEString(), "fileextensions", null, 0, -1, MEditorPartDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getEditorPartDescriptor_Contenttypes(), ecorePackage.getEString(), "contenttypes", null, 0, -1, MEditorPartDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+		// Create resource
+		createResource(eNS_URI);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * Defines literals for the meta objects that represent
+	 * <ul>
+	 *   <li>each class,</li>
+	 *   <li>each feature of each class,</li>
+	 *   <li>each enum,</li>
+	 *   <li>and each data type</li>
+	 * </ul>
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public interface Literals {
+		/**
+		 * The meta object literal for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl <em>Simple IDE Application</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl
+		 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getSimpleIDEApplication()
+		 * @generated
+		 */
+		public static final EClass SIMPLE_IDE_APPLICATION = eINSTANCE.getSimpleIDEApplication();
+
+		/**
+		 * The meta object literal for the '<em><b>Editor Part Descriptors</b></em>' containment reference list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EReference SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS = eINSTANCE.getSimpleIDEApplication_EditorPartDescriptors();
+
+		/**
+		 * The meta object literal for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl <em>Editor Part Descriptor</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl
+		 * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getEditorPartDescriptor()
+		 * @generated
+		 */
+		public static final EClass EDITOR_PART_DESCRIPTOR = eINSTANCE.getEditorPartDescriptor();
+
+		/**
+		 * The meta object literal for the '<em><b>Contribution URI</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI = eINSTANCE.getEditorPartDescriptor_ContributionURI();
+
+		/**
+		 * The meta object literal for the '<em><b>Fileextensions</b></em>' attribute list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS = eINSTANCE.getEditorPartDescriptor_Fileextensions();
+
+		/**
+		 * The meta object literal for the '<em><b>Contenttypes</b></em>' attribute list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		public static final EAttribute EDITOR_PART_DESCRIPTOR__CONTENTTYPES = eINSTANCE.getEditorPartDescriptor_Contenttypes();
+
+	}
+
+} //SimpleidePackageImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideAdapterFactory.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideAdapterFactory.java
new file mode 100644
index 0000000..ca132c4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideAdapterFactory.java
@@ -0,0 +1,389 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleideAdapterFactory.java,v 1.3 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.util;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.*;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindingTableContainer;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer;
+import org.eclipse.e4.ui.model.application.ui.MContext;
+import org.eclipse.e4.ui.model.application.ui.MElementContainer;
+import org.eclipse.e4.ui.model.application.ui.MUIElement;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Adapter Factory</b> for the model.
+ * It provides an adapter <code>createXXX</code> method for each class of the model.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl
+ * @generated
+ */
+public class SimpleideAdapterFactory extends AdapterFactoryImpl {
+	/**
+	 * The cached model package.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected static SimpleidePackageImpl modelPackage;
+
+	/**
+	 * Creates an instance of the adapter factory.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public SimpleideAdapterFactory() {
+		if (modelPackage == null) {
+			modelPackage = SimpleidePackageImpl.eINSTANCE;
+		}
+	}
+
+	/**
+	 * Returns whether this factory is applicable for the type of the object.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model.
+	 * <!-- end-user-doc -->
+	 * @return whether this factory is applicable for the type of the object.
+	 * @generated
+	 */
+	@Override
+	public boolean isFactoryForType(Object object) {
+		if (object == modelPackage) {
+			return true;
+		}
+		if (object instanceof EObject) {
+			return ((EObject)object).eClass().getEPackage() == modelPackage;
+		}
+		return false;
+	}
+
+	/**
+	 * The switch that delegates to the <code>createXXX</code> methods.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected SimpleideSwitch<Adapter> modelSwitch =
+		new SimpleideSwitch<Adapter>() {
+			@Override
+			public Adapter caseSimpleIDEApplication(MSimpleIDEApplication object) {
+				return createSimpleIDEApplicationAdapter();
+			}
+			@Override
+			public Adapter caseEditorPartDescriptor(MEditorPartDescriptor object) {
+				return createEditorPartDescriptorAdapter();
+			}
+			@Override
+			public Adapter caseApplicationElement(MApplicationElement object) {
+				return createApplicationElementAdapter();
+			}
+			@Override
+			public Adapter caseUIElement(MUIElement object) {
+				return createUIElementAdapter();
+			}
+			@Override
+			public <T extends MUIElement> Adapter caseElementContainer(MElementContainer<T> object) {
+				return createElementContainerAdapter();
+			}
+			@Override
+			public Adapter caseContext(MContext object) {
+				return createContextAdapter();
+			}
+			@Override
+			public Adapter caseHandlerContainer(MHandlerContainer object) {
+				return createHandlerContainerAdapter();
+			}
+			@Override
+			public Adapter caseBindingTableContainer(MBindingTableContainer object) {
+				return createBindingTableContainerAdapter();
+			}
+			@Override
+			public Adapter casePartDescriptorContainer(MPartDescriptorContainer object) {
+				return createPartDescriptorContainerAdapter();
+			}
+			@Override
+			public Adapter caseBindings(MBindings object) {
+				return createBindingsAdapter();
+			}
+			@Override
+			public Adapter caseMenuContributions(MMenuContributions object) {
+				return createMenuContributionsAdapter();
+			}
+			@Override
+			public Adapter caseToolBarContributions(MToolBarContributions object) {
+				return createToolBarContributionsAdapter();
+			}
+			@Override
+			public Adapter caseTrimContributions(MTrimContributions object) {
+				return createTrimContributionsAdapter();
+			}
+			@Override
+			public Adapter caseApplication(MApplication object) {
+				return createApplicationAdapter();
+			}
+			@Override
+			public Adapter caseUILabel(MUILabel object) {
+				return createUILabelAdapter();
+			}
+			@Override
+			public Adapter defaultCase(EObject object) {
+				return createEObjectAdapter();
+			}
+		};
+
+	/**
+	 * Creates an adapter for the <code>target</code>.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param target the object to adapt.
+	 * @return the adapter for the <code>target</code>.
+	 * @generated
+	 */
+	@Override
+	public Adapter createAdapter(Notifier target) {
+		return modelSwitch.doSwitch((EObject)target);
+	}
+
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication <em>Simple IDE Application</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication
+	 * @generated
+	 */
+	public Adapter createSimpleIDEApplicationAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor <em>Editor Part Descriptor</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor
+	 * @generated
+	 */
+	public Adapter createEditorPartDescriptorAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.MApplicationElement <em>Element</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.MApplicationElement
+	 * @generated
+	 */
+	public Adapter createApplicationElementAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MUIElement <em>UI Element</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.ui.MUIElement
+	 * @generated
+	 */
+	public Adapter createUIElementAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MElementContainer <em>Element Container</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.ui.MElementContainer
+	 * @generated
+	 */
+	public Adapter createElementContainerAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MContext <em>Context</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.ui.MContext
+	 * @generated
+	 */
+	public Adapter createContextAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.commands.MHandlerContainer <em>Handler Container</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.commands.MHandlerContainer
+	 * @generated
+	 */
+	public Adapter createHandlerContainerAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.commands.MBindingTableContainer <em>Binding Table Container</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.commands.MBindingTableContainer
+	 * @generated
+	 */
+	public Adapter createBindingTableContainerAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer <em>Part Descriptor Container</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer
+	 * @generated
+	 */
+	public Adapter createPartDescriptorContainerAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.commands.MBindings <em>Bindings</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.commands.MBindings
+	 * @generated
+	 */
+	public Adapter createBindingsAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions <em>Contributions</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions
+	 * @generated
+	 */
+	public Adapter createMenuContributionsAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions <em>Tool Bar Contributions</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions
+	 * @generated
+	 */
+	public Adapter createToolBarContributionsAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions <em>Trim Contributions</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions
+	 * @generated
+	 */
+	public Adapter createTrimContributionsAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.MApplication <em>Application</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.MApplication
+	 * @generated
+	 */
+	public Adapter createApplicationAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MUILabel <em>UI Label</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.e4.ui.model.application.ui.MUILabel
+	 * @generated
+	 */
+	public Adapter createUILabelAdapter() {
+		return null;
+	}
+
+	/**
+	 * Creates a new adapter for the default case.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @generated
+	 */
+	public Adapter createEObjectAdapter() {
+		return null;
+	}
+
+} //SimpleideAdapterFactory
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideSwitch.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideSwitch.java
new file mode 100644
index 0000000..d58e412
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideSwitch.java
@@ -0,0 +1,376 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleideSwitch.java,v 1.3 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.util;
+
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.*;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindingTableContainer;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer;
+import org.eclipse.e4.ui.model.application.ui.MContext;
+import org.eclipse.e4.ui.model.application.ui.MElementContainer;
+import org.eclipse.e4.ui.model.application.ui.MUIElement;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Switch</b> for the model's inheritance hierarchy.
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)}
+ * to invoke the <code>caseXXX</code> method for each class of the model,
+ * starting with the actual class of the object
+ * and proceeding up the inheritance hierarchy
+ * until a non-null result is returned,
+ * which is the result of the switch.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl
+ * @generated
+ */
+public class SimpleideSwitch<T1> {
+	/**
+	 * The cached model package
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected static SimpleidePackageImpl modelPackage;
+
+	/**
+	 * Creates an instance of the switch.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public SimpleideSwitch() {
+		if (modelPackage == null) {
+			modelPackage = SimpleidePackageImpl.eINSTANCE;
+		}
+	}
+
+	/**
+	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the first non-null result returned by a <code>caseXXX</code> call.
+	 * @generated
+	 */
+	public T1 doSwitch(EObject theEObject) {
+		return doSwitch(theEObject.eClass(), theEObject);
+	}
+
+	/**
+	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the first non-null result returned by a <code>caseXXX</code> call.
+	 * @generated
+	 */
+	protected T1 doSwitch(EClass theEClass, EObject theEObject) {
+		if (theEClass.eContainer() == modelPackage) {
+			return doSwitch(theEClass.getClassifierID(), theEObject);
+		}
+		else {
+			List<EClass> eSuperTypes = theEClass.getESuperTypes();
+			return
+				eSuperTypes.isEmpty() ?
+					defaultCase(theEObject) :
+					doSwitch(eSuperTypes.get(0), theEObject);
+		}
+	}
+
+	/**
+	 * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the first non-null result returned by a <code>caseXXX</code> call.
+	 * @generated
+	 */
+	protected T1 doSwitch(int classifierID, EObject theEObject) {
+		switch (classifierID) {
+			case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION: {
+				MSimpleIDEApplication simpleIDEApplication = (MSimpleIDEApplication)theEObject;
+				T1 result = caseSimpleIDEApplication(simpleIDEApplication);
+				if (result == null) result = caseApplication(simpleIDEApplication);
+				if (result == null) result = caseElementContainer(simpleIDEApplication);
+				if (result == null) result = caseContext(simpleIDEApplication);
+				if (result == null) result = caseHandlerContainer(simpleIDEApplication);
+				if (result == null) result = caseBindingTableContainer(simpleIDEApplication);
+				if (result == null) result = casePartDescriptorContainer(simpleIDEApplication);
+				if (result == null) result = caseBindings(simpleIDEApplication);
+				if (result == null) result = caseMenuContributions(simpleIDEApplication);
+				if (result == null) result = caseToolBarContributions(simpleIDEApplication);
+				if (result == null) result = caseTrimContributions(simpleIDEApplication);
+				if (result == null) result = caseUIElement(simpleIDEApplication);
+				if (result == null) result = caseApplicationElement(simpleIDEApplication);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR: {
+				MEditorPartDescriptor editorPartDescriptor = (MEditorPartDescriptor)theEObject;
+				T1 result = caseEditorPartDescriptor(editorPartDescriptor);
+				if (result == null) result = caseApplicationElement(editorPartDescriptor);
+				if (result == null) result = caseUILabel(editorPartDescriptor);
+				if (result == null) result = caseHandlerContainer(editorPartDescriptor);
+				if (result == null) result = caseBindings(editorPartDescriptor);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			default: return defaultCase(theEObject);
+		}
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Simple IDE Application</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Simple IDE Application</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseSimpleIDEApplication(MSimpleIDEApplication object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Editor Part Descriptor</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Editor Part Descriptor</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseEditorPartDescriptor(MEditorPartDescriptor object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Element</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Element</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseApplicationElement(MApplicationElement object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>UI Element</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>UI Element</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseUIElement(MUIElement object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Element Container</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Element Container</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public <T extends MUIElement> T1 caseElementContainer(MElementContainer<T> object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Context</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Context</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseContext(MContext object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Handler Container</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Handler Container</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseHandlerContainer(MHandlerContainer object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Binding Table Container</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Binding Table Container</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseBindingTableContainer(MBindingTableContainer object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Part Descriptor Container</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Part Descriptor Container</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 casePartDescriptorContainer(MPartDescriptorContainer object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Bindings</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Bindings</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseBindings(MBindings object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Contributions</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Contributions</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseMenuContributions(MMenuContributions object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Tool Bar Contributions</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Tool Bar Contributions</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseToolBarContributions(MToolBarContributions object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Trim Contributions</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Trim Contributions</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseTrimContributions(MTrimContributions object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Application</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Application</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseApplication(MApplication object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>UI Label</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>UI Label</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T1 caseUILabel(MUILabel object) {
+		return null;
+	}
+
+	/**
+	 * Returns the result of interpreting the object as an instance of '<em>EObject</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch, but this is the last case anyway.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>EObject</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject)
+	 * @generated
+	 */
+	public T1 defaultCase(EObject object) {
+		return null;
+	}
+
+} //SimpleideSwitch
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.classpath b/examples/org.eclipse.e4.demo.simpleide.navigator/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.project b/examples/org.eclipse.e4.demo.simpleide.navigator/.project
new file mode 100644
index 0000000..c7b9ea1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.navigator</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a90d081
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Wed Jun 02 15:49:37 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..a70c776
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:53 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.navigator/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e752b9f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0reators.exsd"/>
+Bundle-ManifestVersion: 2
+Bundle-Name: Navigator
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.navigator;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.core.databinding;bundle-version="1.3.100",
+ org.eclipse.core.databinding.observable;bundle-version="1.3.0",
+ org.eclipse.jface.databinding;bundle-version="1.4.0",
+ org.eclipse.core.databinding.property;bundle-version="1.3.0",
+ org.eclipse.e4.core.commands;bundle-version="0.9.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1"
+Import-Package: javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0",
+ org.eclipse.core.runtime.jobs,
+ org.eclipse.e4.ui.workbench.swt.modeling
+Service-Component: OSGI-INF/serviceRegistryComponent.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/OSGI-INF/serviceRegistryComponent.xml b/examples/org.eclipse.e4.demo.simpleide.navigator/OSGI-INF/serviceRegistryComponent.xml
new file mode 100644
index 0000000..78c8801
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/OSGI-INF/serviceRegistryComponent.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="false" name="org.eclipse.e4.demo.simpleide.navigator.projectCreatorComponent">
+   <implementation class="org.eclipse.e4.demo.simpleide.navigator.internal.ServiceRegistryComponent"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.simpleide.navigator.internal.ServiceRegistryComponent"/>
+   </service>
+   <reference bind="addProjectService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.IProjectService" name="IProjectService" policy="dynamic" unbind="removeProjectService"/>
+   <reference bind="addImportService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.IImportResourceService" name="IImportResourceService" policy="dynamic" unbind="removeImportService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/build.properties b/examples/org.eclipse.e4.demo.simpleide.navigator/build.properties
new file mode 100644
index 0000000..c25a12f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/build.properties
@@ -0,0 +1,8 @@
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               OSGI-INF/,\
+               icons/,\
+               xmi/
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png b/examples/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png
new file mode 100644
index 0000000..f04a52b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.navigator/plugin.xml
new file mode 100644
index 0000000..a884178
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/plugin.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id1"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+      <fragment
+            uri="xmi/contextViewMenuFragment.e4xmi">
+      </fragment>
+   </extension>
+   <extension
+         point="org.eclipse.core.expressions.definitions">
+      <definition
+            id="org.eclipse.e4.demo.simpleide.menu.selection.Entry">
+         <with
+               variable="output.selection">
+            <count
+                  value="1">
+            </count>
+            <iterate
+                  ifEmpty="false"
+                  operator="and">
+               <adapt
+                     type="org.eclipse.e4.demo.simpleide.menu.ContextMenuView$Entry">
+               </adapt>
+            </iterate>
+         </with>
+      </definition>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuView.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuView.java
new file mode 100644
index 0000000..289afa2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuView.java
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.menu;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import org.eclipse.e4.core.commands.EHandlerService;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.e4.ui.workbench.swt.modeling.EMenuService;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.TreeColumn;
+
+public class ContextMenuView {
+	public static final String ITEMS_MENU = "ContextMenuView.treeMenu";
+	public static final String TAGS_MENU = "ContextMenuView.tags";
+	public static final String INFO_MENU = "ContextMenuView.info";
+
+	static class Entry {
+		final public Date date;
+		final public String desc;
+
+		public Entry(Date d, String s) {
+			date = d;
+			desc = s;
+		}
+	}
+
+	static class Tag {
+		final public String name;
+
+		public Tag(String s) {
+			name = s;
+		}
+	}
+
+	private TreeViewer items;
+	private ListViewer tagList;
+	private Text info;
+
+	@Inject
+	private ESelectionService selectionService;
+
+	@Inject
+	private EHandlerService handlerService;
+
+	@Inject
+	private EMenuService menuService;
+
+	@Inject
+	public ContextMenuView(final Composite parent) {
+		final Composite root = new Composite(parent, SWT.NONE);
+		root.setLayout(new GridLayout(2, true));
+		items = new TreeViewer(root, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+		items.getControl().setLayoutData(
+				new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+		TreeViewerColumn dateColumn = new TreeViewerColumn(items, SWT.LEFT);
+		TreeColumn dcol = dateColumn.getColumn();
+		dcol.setText("Date");
+		dcol.setWidth(200);
+		TreeViewerColumn descColumn = new TreeViewerColumn(items, SWT.LEFT);
+		TreeColumn descCol = descColumn.getColumn();
+		descCol.setText("Description");
+		descCol.setWidth(300);
+		tagList = new ListViewer(root, SWT.MULTI | SWT.V_SCROLL);
+		tagList.getControl().setLayoutData(
+				new GridData(SWT.FILL, SWT.FILL, false, true));
+		info = new Text(root, SWT.MULTI | SWT.READ_ONLY);
+		info.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
+	}
+
+	ArrayList<Entry> itemModel = new ArrayList<Entry>();
+	HashMap<Entry, String> textMap = new HashMap<Entry, String>();
+	HashMap<Entry, ArrayList<Tag>> tagMap = new HashMap<Entry, ArrayList<Tag>>();
+	private CopyHandler itemCopyHandler;
+	private CopyHandler tagCopyHandler;
+	private Object infoCopyHandler;
+
+	class ViewContentProvider implements IStructuredContentProvider,
+			ITreeContentProvider {
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+
+		public void dispose() {
+		}
+
+		public Object[] getElements(Object inputElement) {
+			if (inputElement instanceof ArrayList<?>) {
+				return ((ArrayList<?>) inputElement).toArray();
+			}
+			return null;
+		}
+
+		public boolean hasChildren(Object element) {
+			if (element instanceof ArrayList<?>) {
+				return true;
+			}
+			return false;
+		}
+
+		public Object getParent(Object element) {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		public Object[] getChildren(Object parentElement) {
+			if (parentElement instanceof ArrayList<?>) {
+				return ((ArrayList<?>) parentElement).toArray();
+			}
+			return new Object[0];
+		}
+	}
+
+	static class CopyHandler {
+		StructuredViewer viewer;
+		Display display;
+
+		public CopyHandler(Display d, StructuredViewer v) {
+			viewer = v;
+			display = d;
+		}
+
+		@CanExecute
+		public boolean canExecute() {
+			ISelection sel = viewer.getSelection();
+			System.out.println("canExecute: " + sel);
+			return sel != null && sel instanceof IStructuredSelection
+					&& !((IStructuredSelection) sel).isEmpty();
+		}
+
+		@Execute
+		public void execute() {
+			Clipboard cb = new Clipboard(display);
+			TextTransfer t = TextTransfer.getInstance();
+			String text = getText();
+			System.out.println("execute: " + text);
+			cb.setContents(new Object[] { text }, new Transfer[] { t });
+			cb.dispose();
+		}
+
+		private String getText() {
+			ISelection sel = viewer.getSelection();
+			if (sel instanceof IStructuredSelection) {
+				IStructuredSelection ssel = (IStructuredSelection) sel;
+				Object obj = ssel.getFirstElement();
+				if (obj instanceof Entry) {
+					return ((Entry) obj).desc
+							+ " ("
+							+ SimpleDateFormat.getInstance().format(
+									((Entry) obj).date) + ")";
+				} else if (obj instanceof Tag) {
+					return ((Tag) obj).name;
+				}
+			}
+			return "";
+		}
+	}
+
+	@PostConstruct
+	public void init() {
+		for (int i = 1; i < 5; i++) {
+			createEntry(i);
+		}
+
+		items.setContentProvider(new ViewContentProvider());
+		items.setLabelProvider(new EntryLabelProvider());
+		items.setInput(itemModel);
+		items.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				ISelection selection = event.getSelection();
+				selectionService.setSelection(selection);
+				if (selection instanceof IStructuredSelection) {
+					Entry e = (Entry) ((IStructuredSelection) selection)
+							.getFirstElement();
+					String text = textMap.get(e);
+					info.setText(text == null ? "" : text);
+					ArrayList<Tag> list = tagMap.get(e);
+					tagList.setInput(list == null ? Collections.EMPTY_LIST
+							: list);
+				}
+			}
+		});
+
+		items.getTree().setLinesVisible(true);
+		items.getTree().setHeaderVisible(true);
+		items.getTree().layout(true);
+		menuService.registerContextMenu(items.getControl(), ITEMS_MENU);
+
+		itemCopyHandler = new CopyHandler(items.getTree().getDisplay(), items);
+		items.getTree().addListener(SWT.Activate, new Listener() {
+			public void handleEvent(Event event) {
+				handlerService.activateHandler("org.eclipse.ui.edit.copy",
+						itemCopyHandler);
+			}
+		});
+
+		tagList.setContentProvider(new ArrayContentProvider());
+		tagList.setLabelProvider(new LabelProvider() {
+			@Override
+			public String getText(Object element) {
+				if (element instanceof Tag) {
+					return ((Tag) element).name;
+				}
+				return null;
+			}
+		});
+		final MPopupMenu tagPopupMenu = menuService.registerContextMenu(tagList.getControl(),
+				TAGS_MENU);
+		tagList.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				ISelection selection = event.getSelection();
+				ESelectionService srv = tagPopupMenu.getContext().get(
+						ESelectionService.class);
+				srv.setSelection(selection);
+			}
+		});
+
+		tagCopyHandler = new CopyHandler(tagList.getControl().getDisplay(),
+				tagList);
+		tagList.getControl().addListener(SWT.Activate, new Listener() {
+			public void handleEvent(Event event) {
+				handlerService.activateHandler("org.eclipse.ui.edit.copy",
+						tagCopyHandler);
+			}
+		});
+
+		// with no handler, CTRL+C works because it delegates
+		// to the native widget.  But the menu item copy
+		// doesn't, since it will not be handled.
+		// This will work as a real handler for both situations.
+		infoCopyHandler = new Object() {
+			@CanExecute
+			public boolean canExecute() {
+				return info.getSelectionCount() > 0;
+			}
+
+			@Execute
+			public void execute() {
+				info.copy();
+			}
+		};
+
+		info.addListener(SWT.Activate, new Listener() {
+			public void handleEvent(Event event) {
+				// just remove 'em both for simplicity
+				handlerService.deactivateHandler("org.eclipse.ui.edit.copy",
+						itemCopyHandler);
+				handlerService.deactivateHandler("org.eclipse.ui.edit.copy",
+						tagCopyHandler);
+				handlerService.activateHandler("org.eclipse.ui.edit.copy",
+						infoCopyHandler);
+			}
+		});
+		final MPopupMenu infoPopupMenu = menuService.registerContextMenu(info,
+				INFO_MENU);
+		// we can either publish the Text selection as a
+		// org.eclipse.jface.text.TextSelection or set it to an empty selection.
+		// I picked empty.
+		ESelectionService srv = infoPopupMenu.getContext().get(
+				ESelectionService.class);
+		srv.setSelection(StructuredSelection.EMPTY);
+	}
+
+	private static class EntryLabelProvider extends LabelProvider implements
+			ITableLabelProvider {
+		public Image getColumnImage(Object element, int columnIndex) {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see
+		 * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+		 */
+		@Override
+		public String getText(Object element) {
+			return getColumnText(element, 0);
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+			switch (columnIndex) {
+			case 0:
+				return SimpleDateFormat.getInstance().format(
+						((Entry) element).date);
+			case 1:
+				return ((Entry) element).desc;
+			}
+			return null;
+		}
+	}
+
+	private void createEntry(int index) {
+		Entry e = new Entry(new Date(), "item " + index);
+		itemModel.add(e);
+		textMap.put(e, "text for item " + index);
+		ArrayList<Tag> tags = new ArrayList<Tag>();
+		tagMap.put(e, tags);
+		for (int i = 1; i < 5; i++) {
+			createTag(tags, index, i);
+		}
+	}
+
+	private void createTag(ArrayList<Tag> tags, int index, int i) {
+		tags.add(new Tag("item_" + index + "_tag_" + i));
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuViewProcessor.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuViewProcessor.java
new file mode 100644
index 0000000..942b655
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuViewProcessor.java
@@ -0,0 +1,122 @@
+package org.eclipse.e4.demo.simpleide.menu;
+
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MHandler;
+import org.eclipse.e4.ui.model.application.commands.impl.CommandsFactoryImpl;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
+import org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicFactoryImpl;
+import org.eclipse.e4.ui.model.application.ui.MCoreExpression;
+import org.eclipse.e4.ui.model.application.ui.impl.UiFactoryImpl;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
+import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
+import org.eclipse.emf.ecore.EObject;
+
+public class ContextMenuViewProcessor  {
+
+	public static final String OPEN_DIALOG_COMMAND = "org.eclipse.e4.demo.simpleide.menu.contextDialog";
+
+	public void processElement(EObject parent) {
+		if (!(parent instanceof MApplication)) {
+			return;
+		}
+		MApplication app = (MApplication) parent;
+
+		createCommand(app);
+		MPartDescriptor desc = BasicFactoryImpl.eINSTANCE
+				.createPartDescriptor();
+		desc.setLabel("Context Menu View");
+		desc.setElementId("org.eclipse.e4.demo.simpleide.menu.ContextMenuView");
+		desc.setCategory("org.eclipse.e4.secondaryDataStack");
+		desc.setContributionURI("bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.ContextMenuView");
+
+		MMenu menu = MenuFactoryImpl.eINSTANCE.createMenu();
+		menu.getTags().add("ViewMenu");
+		menu.setElementId("org.eclipse.e4.demo.simpleide.menu.ContextMenuView");
+
+		MHandledMenuItem item = MenuFactoryImpl.eINSTANCE
+				.createHandledMenuItem();
+		item.setElementId("e4.showView");
+		item.setLabel("Show View");
+		item.setCommand(findCommand(app, "org.eclipse.ui.views.showView"));
+		menu.getChildren().add(item);
+
+		// add it to the part
+		desc.getMenus().add(menu);
+
+		// context menu
+		menu = createPopupMenu(app, ContextMenuView.ITEMS_MENU, "Items");
+		// add it to the part
+		desc.getMenus().add(menu);
+
+		// context menu
+		menu = createPopupMenu(app, ContextMenuView.TAGS_MENU, "Tags");
+		// add it to the part
+		desc.getMenus().add(menu);
+
+		// context menu
+		menu = createPopupMenu(app, ContextMenuView.INFO_MENU, "Info");
+		// add it to the part
+		desc.getMenus().add(menu);
+
+		app.getDescriptors().add(desc);
+	}
+
+	private void createCommand(MApplication app) {
+		MCommand cmd = CommandsFactoryImpl.eINSTANCE.createCommand();
+		cmd.setElementId(OPEN_DIALOG_COMMAND);
+		cmd.setCommandName("Show Info");
+		MHandler handler = CommandsFactoryImpl.eINSTANCE.createHandler();
+		handler.setCommand(cmd);
+		handler.setElementId("open.dialog.on.selection");
+		handler.setContributionURI("bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.OpenDialogHandler");
+		app.getCommands().add(cmd);
+		app.getHandlers().add(handler);
+	}
+
+	private MMenu createPopupMenu(MApplication app, String id, String name) {
+		MMenu menu = MenuFactoryImpl.eINSTANCE.createPopupMenu();
+		menu.setElementId(id);
+
+		MHandledMenuItem item = MenuFactoryImpl.eINSTANCE
+				.createHandledMenuItem();
+		item.setElementId("e4.showView");
+		item.setLabel("Show View " + name);
+		item.setCommand(findCommand(app, "org.eclipse.ui.views.showView"));
+		menu.getChildren().add(item);
+
+		MMenuSeparator sep = MenuFactoryImpl.eINSTANCE.createMenuSeparator();
+		sep.setElementId("additions");
+		menu.getChildren().add(sep);
+
+		item = MenuFactoryImpl.eINSTANCE.createHandledMenuItem();
+		item.setElementId("copy");
+		item.setLabel("Copy");
+		item.setCommand(findCommand(app, "org.eclipse.ui.edit.copy"));
+		menu.getChildren().add(item);
+
+		MCoreExpression exp = UiFactoryImpl.eINSTANCE.createCoreExpression();
+		exp.setCoreExpressionId("org.eclipse.e4.demo.simpleide.menu.selection.Entry");
+		item = MenuFactoryImpl.eINSTANCE.createHandledMenuItem();
+		MCommand cmd = findCommand(app, OPEN_DIALOG_COMMAND);
+		item.setElementId(cmd.getElementId());
+		item.setLabel(cmd.getCommandName());
+		item.setCommand(cmd);
+		item.setVisibleWhen(exp);
+		menu.getChildren().add(item);
+
+		return menu;
+	}
+
+	private MCommand findCommand(MApplication app, String id) {
+		for (MCommand cmd : app.getCommands()) {
+			if (id.equals(cmd.getElementId())) {
+				return cmd;
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/OpenDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/OpenDialogHandler.java
new file mode 100644
index 0000000..dc77877
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/OpenDialogHandler.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.menu;
+
+import javax.inject.Named;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.services.IServiceConstants;
+
+public class OpenDialogHandler {
+	@CanExecute
+	public boolean canExecute(
+			@Named(IServiceConstants.SELECTION) @Optional ContextMenuView.Tag tag) {
+		return tag != null;
+	}
+
+	@Execute
+	public void execute(
+			@Named(IServiceConstants.SELECTION) @Optional ContextMenuView.Tag tag) {
+		System.out.println(tag.name);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ResourceNavigator.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ResourceNavigator.java
new file mode 100644
index 0000000..5a04163
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ResourceNavigator.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.navigator.internal;
+
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.Observables;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.observable.set.WritableSet;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.commands.EHandlerService;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.services.IImportResourceService;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.databinding.viewers.ObservableSetTreeContentProvider;
+import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
+import org.eclipse.jface.viewers.IOpenListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+public class ResourceNavigator {
+	private Map<IContainer, IObservableSet> observableSets = new HashMap<IContainer, IObservableSet>();
+	
+	@Inject
+	private ECommandService commandService;
+	
+	@Inject
+	private EHandlerService handlerService;
+
+	private IResourceChangeListener listener = new IResourceChangeListener() {
+		public void resourceChanged(IResourceChangeEvent event) {
+			if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+				try {
+					event.getDelta().accept(new IResourceDeltaVisitor() {
+						public boolean visit(IResourceDelta delta)
+								throws CoreException {
+							if (delta.getKind() == IResourceDelta.ADDED) {
+								handleChange(delta.getResource(), delta
+										.getResource().getParent(), true);
+							} else if (delta.getKind() == IResourceDelta.REMOVED) {
+								handleChange(delta.getResource(), delta
+										.getResource().getParent(), false);
+							}
+							return true;
+						}
+
+						private void handleChange(final IResource resource,
+								final IContainer parent, final boolean added) {
+							final IObservableSet set = observableSets
+									.get(parent);
+							Realm realm = set != null ? set.getRealm() : null;
+							if (realm != null) {
+								realm.asyncExec(new Runnable() {
+									public void run() {
+										if (added) {
+											set.add(resource);
+										} else {
+											set.remove(resource);
+										}
+									}
+								});
+							}
+						}
+					});
+				} catch (CoreException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+	};
+
+	private IEclipseContext context;
+
+	@Inject
+	private ServiceRegistryComponent serviceRegistry;
+
+	@Inject
+	private MApplication application;
+	
+	@Inject
+	private ESelectionService selectionService;
+	
+	@Inject
+	public ResourceNavigator(Composite parent, final IEclipseContext context, IWorkspace workspace) {
+		final Realm realm = SWTObservables.getRealm(parent.getDisplay());
+		this.context = context;
+		parent.setLayout(new FillLayout());
+		TreeViewer viewer = new TreeViewer(parent,SWT.FULL_SELECTION|SWT.H_SCROLL|SWT.V_SCROLL);
+		viewer.addSelectionChangedListener(new ISelectionChangedListener(){
+			public void selectionChanged(SelectionChangedEvent event) {
+				StructuredSelection selection = (StructuredSelection)event.getSelection();
+				selectionService.setSelection(selection.size() == 1 ? selection.getFirstElement() : selection.toArray());
+//				context.modify(IServiceConstants.ACTIVE_SELECTION, selection.size() == 1 ? selection.getFirstElement() : selection.toArray());
+			}
+		});
+		
+		IObservableFactory setFactory = new IObservableFactory() {
+			public IObservable createObservable(Object element) {
+				if (element instanceof IContainer
+						&& ((IContainer) element).exists()) {
+					IObservableSet observableSet = observableSets.get(element);
+					if (observableSet == null) {
+						observableSet = new WritableSet(realm);
+						try {
+							observableSet.addAll(Arrays
+									.asList(((IContainer) element).members()));
+						} catch (CoreException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+						observableSets.put((IContainer) element, observableSet);
+					}
+					return observableSet;
+				}
+				return Observables.emptyObservableSet();
+			}
+		};
+		viewer.setContentProvider(new ObservableSetTreeContentProvider(
+				setFactory, new TreeStructureAdvisor() {
+					public Boolean hasChildren(Object element) {
+						return Boolean.valueOf(element instanceof IContainer);
+					}
+				}));
+
+		viewer.setLabelProvider(new LabelProvider() {
+			public String getText(Object element) {
+				if (element instanceof IResource)
+					return ((IResource) element).getName();
+				return element == null ? "" : element.toString();
+			}
+		});
+		viewer.setSorter(new ViewerSorter());
+		viewer.setInput(workspace.getRoot());
+		viewer.addOpenListener(new IOpenListener() {
+			
+			public void open(OpenEvent event) {
+				MSimpleIDEApplication app = (MSimpleIDEApplication) application;
+				IStructuredSelection s = (IStructuredSelection) event.getSelection();
+				for( Object o : s.toArray() ) {
+					if( o instanceof IFile ) {
+						IFile f = (IFile) o;
+						context.set(IFile.class, f);
+						String fExt = f.getFileExtension();
+						EDITOR: for( MEditorPartDescriptor desc : app.getEditorPartDescriptors() ) {
+							for( String ext: desc.getFileextensions() ) {
+								if( ext.equals(fExt) ) {
+									context.set(MEditorPartDescriptor.class, desc);
+									System.err.println("Opening with: " + desc);
+									
+									Command cmd = commandService.getCommand("simpleide.command.openeditor");
+									ParameterizedCommand pCmd = ParameterizedCommand.generateCommand(cmd, null);
+									handlerService.executeHandler(pCmd);
+									
+									break EDITOR;
+								}
+							}
+						}
+					}
+				}
+				
+			}
+		});
+		setupContextMenu(viewer, parent.getShell());
+		workspace.addResourceChangeListener(listener);
+	}
+	
+	private void setupContextMenu(final TreeViewer viewer, final Shell shell) {
+		MenuManager mgr = new MenuManager();
+		viewer.getControl().setMenu(mgr.createContextMenu(viewer.getControl()));
+		
+		mgr.setRemoveAllWhenShown(true);
+		mgr.addMenuListener(new IMenuListener() {
+			
+			public void menuAboutToShow(IMenuManager manager) {
+				MenuManager mgr = new MenuManager("Import");
+				for( IImportResourceService s : serviceRegistry.getImportServices() ) {
+					final IImportResourceService tmp = s;
+					Action a = new Action(s.getLabel()) {
+						public void run() {
+							tmp.importResource(shell, context.createChild());
+						}
+					};
+					mgr.add(a);
+				}
+				
+				manager.add(mgr);
+			}
+		});
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ServiceRegistryComponent.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ServiceRegistryComponent.java
new file mode 100644
index 0000000..5a19917
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ServiceRegistryComponent.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.navigator.internal;
+
+import java.util.Vector;
+import org.eclipse.e4.demo.simpleide.services.IImportResourceService;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+
+public class ServiceRegistryComponent {
+	private Vector<IProjectService> creators = new Vector<IProjectService>();
+	private Vector<IImportResourceService> importServices = new Vector<IImportResourceService>();
+	
+	public void addProjectService( IProjectService creator ) {
+		creators.add(creator);
+	}
+	
+	public void removeProjectService(IProjectService creator) {
+		creators.remove(creator);
+	}
+	
+	public Vector<IProjectService> getCreators() {
+		return creators;
+	}
+	
+	public void addImportService(IImportResourceService importService) {
+		importServices.add(importService);
+	}
+	
+	public void removeImportService(IImportResourceService importService) {
+		importServices.remove(importService);
+	}
+	
+	public Vector<IImportResourceService> getImportServices() {
+		return importServices;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/contextViewMenuFragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/contextViewMenuFragment.e4xmi
new file mode 100644
index 0000000..cf0225f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/contextViewMenuFragment.e4xmi
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/descriptor/basic" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:ui="http://www.eclipse.org/ui/2010/UIModel/application/ui" xmi:id="_uj3fEHZcEd-RApwktjxCFQ">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_5w9CkHZcEd-RApwktjxCFQ" featurename="commands" parentElementId="app.simpleide">
+    <elements xsi:type="commands:Command" xmi:id="_NtAhUHZdEd-izNVw4-awdw" elementId="open.dialog.on.selection" commandName="Show Info"/>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_TaVQgHZdEd-izNVw4-awdw" featurename="handlers" parentElementId="app.simpleide">
+    <elements xsi:type="commands:Handler" xmi:id="_W8wOYHZdEd-izNVw4-awdw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.OpenDialogHandler" command="_NtAhUHZdEd-izNVw4-awdw"/>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_lAjq4HZeEd-R6aDhnXWjVw" featurename="descriptors" parentElementId="app.simpleide">
+    <elements xsi:type="basic:PartDescriptor" xmi:id="_wtS-0HZeEd-R6aDhnXWjVw" label="Context Menu View" elementId="org.eclipse.e4.demo.simpleide.menu.ContextMenuView" category="org.eclipse.e4.secondaryDataStack" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.ContextMenuView">
+      <tags>View</tags>
+      <tags>categoryTag:Utilities</tags>
+      <menus xmi:id="_JWJ4wV6WEd-kocunFhpHRA" elementId="org.eclipse.e4.demo.simpleide.menu.ContextMenuView">
+        <tags>ViewMenu</tags>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpHRA" elementId="e4.showView" label="Show View" >
+          <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+        </children>
+      </menus>
+      <menus xsi:type="menu:PopupMenu" xmi:id="ContextMenuView.treeMenu" elementId="ContextMenuView.treeMenu">
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpH" elementId="e4.showView" >
+          <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+        </children>
+        <children xsi:type="menu:MenuSeparator" xmi:id="_O5FV0F6WEd-kocunFhpHY" elementId="additions"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocuFhpH" elementId="e4.copy">
+          <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.edit.copy"/>
+        </children>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog" command="_NtAhUHZdEd-izNVw4-awdw">
+          <visibleWhen xsi:type="ui:CoreExpression" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry" />
+        </children>
+      </menus>
+      <menus xsi:type="menu:PopupMenu" xmi:id="ContextMenuView.tags" elementId="ContextMenuView.tags">
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpH" elementId="e4.showView" >
+          <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+        </children>
+        <children xsi:type="menu:MenuSeparator" xmi:id="_O5FV0F6WEd-kocunFhpHY" elementId="additions"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocuFhpH" elementId="e4.copy" >
+          <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.edit.copy"/>
+        </children>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog" command="_NtAhUHZdEd-izNVw4-awdw">
+          <visibleWhen xsi:type="ui:CoreExpression" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry" />
+        </children>
+      </menus>
+      <menus xsi:type="menu:PopupMenu" xmi:id="ContextMenuView.info" elementId="ContextMenuView.info">
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpH" elementId="e4.showView" >
+          <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+        </children>
+        <children xsi:type="menu:MenuSeparator" xmi:id="_O5FV0F6WEd-kocunFhpHY" elementId="additions"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocuFhpH" elementId="e4.copy">
+          <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.edit.copy"/>
+        </children>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog" command="_NtAhUHZdEd-izNVw4-awdw">
+          <visibleWhen xsi:type="ui:CoreExpression" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry" />
+        </children>
+      </menus>
+    </elements>
+  </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_6lwRsHZeEd-R6aDhnXWjVw" featurename="menuContributions" parentElementId="app.simpleide">
+    <elements xsi:type="menu:MenuContribution" xmi:id="_Cwp2kHZfEd-R6aDhnXWjVw" elementId="simpleide.info.popup1" parentId="popup">
+      <visibleWhen xsi:type="ui:CoreExpression" xmi:id="_O9PSwHZgEd-o_pkn-4-GGQ" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry"/>
+      <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.1" label="Popup Open 1" command="_NtAhUHZdEd-izNVw4-awdw"/>
+      <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.2" label="Popup Open 2" command="_NtAhUHZdEd-izNVw4-awdw"/>
+      <children xsi:type="menu:Menu" xmi:id="simpleide.submenu" elementId="simpleide.submenu" label="Popup Sub">
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.3" label="Popup Open 3" command="_NtAhUHZdEd-izNVw4-awdw"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.4" label="Popup Open 4" command="_NtAhUHZdEd-izNVw4-awdw"/>
+      </children>
+    </elements>
+    <elements xsi:type="menu:MenuContribution" xmi:id="_GrRSAHZfEd-R6aDhnXWjVw" elementId="simpleide.info.contrib" parentId="_WbMXYEjUEd-v7fhjaiz65w">
+    	<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 1"   elementId="e4.open.dialog.5" command="_NtAhUHZdEd-izNVw4-awdw"/>
+		<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 2"   elementId="e4.open.dialog.6" command="_NtAhUHZdEd-izNVw4-awdw"/>
+        <children xsi:type="menu:Menu" xmi:id="simpleide.window.submenu" elementId="simpleide.window.submenu" label="Window Sub">
+			<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 3"   elementId="e4.open.dialog.7" command="_NtAhUHZdEd-izNVw4-awdw"/>
+			<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 4"   elementId="e4.open.dialog.8" command="_NtAhUHZdEd-izNVw4-awdw"/>
+        </children>
+    </elements>
+    <elements xsi:type="menu:MenuContribution" xmi:id="_Vf3uwHZfEd-R6aDhnXWjVw" elementId="simpleide.info.contrib2" parentId="simpleide.window.submenu">
+		<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 5"   elementId="e4.open.dialog.9" command="_NtAhUHZdEd-izNVw4-awdw"/>
+		<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 6"   elementId="e4.open.dialog.10" command="_NtAhUHZdEd-izNVw4-awdw"/>
+        <children xsi:type="menu:Menu" xmi:id="simpleide.window.submenu2" elementId="simpleide.window.submenu2" label="Window Sub2">
+			<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 7"   elementId="e4.open.dialog.11" command="_NtAhUHZdEd-izNVw4-awdw"/>
+			<children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 8"   elementId="e4.open.dialog.12" command="_NtAhUHZdEd-izNVw4-awdw"/>
+        </children>
+    </elements>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/fragment.e4xmi
new file mode 100644
index 0000000..97547ea
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/fragment.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_WisR8HZEEd-peaY5fFiGdQ">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_ZN23sHZEEd-peaY5fFiGdQ" featurename="children" parentElementId="org.eclipse.e4.primaryNavigationStack">
+    <elements xsi:type="basic:Part" xmi:id="_81XEMHZbEd-Sp-lHczMPZw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.navigator.internal.ResourceNavigator" label="Navigator" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png"/>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/.classpath b/examples/org.eclipse.e4.demo.simpleide.outline/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/.project b/examples/org.eclipse.e4.demo.simpleide.outline/.project
new file mode 100644
index 0000000..3c58498
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.outline</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.outline/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9cfae69
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed May 26 00:00:14 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.outline/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2574993
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Outline
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.outline;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.e4.ui.model.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1"
+Export-Package: org.eclipse.e4.demo.simpleide.outline
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/build.properties b/examples/org.eclipse.e4.demo.simpleide.outline/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif b/examples/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif
new file mode 100644
index 0000000..0dc862c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.outline/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         id="id1"
+         point="org.eclipse.e4.workbench.model">
+      <fragment
+            uri="xmi/fragment.e4xmi">
+      </fragment>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/IOutlinePageProvider.java b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/IOutlinePageProvider.java
new file mode 100644
index 0000000..6b72161
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/IOutlinePageProvider.java
@@ -0,0 +1,5 @@
+package org.eclipse.e4.demo.simpleide.outline;
+
+public interface IOutlinePageProvider {
+	public Class<?> getOutlineClass();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/internal/OutlineView.java b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/internal/OutlineView.java
new file mode 100644
index 0000000..ba29f30
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/internal/OutlineView.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.outline.internal;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.demo.simpleide.outline.IOutlinePageProvider;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+public class OutlineView {
+	private Composite parent;
+
+	private Control pageControl;
+
+	private IEclipseContext pageContext;
+
+	@Inject
+	public OutlineView(Composite parent) {
+		this.parent = parent;
+	}
+
+	@Inject
+	public void setActivePart(
+			@Optional @Named(IServiceConstants.ACTIVE_PART) MPart activePart) {
+		if (parent.isDisposed()) {
+			return;
+		}
+		IEclipseContext oldPageContext = pageContext;
+		Control oldPageControl = pageControl;
+
+		if (activePart != null) {
+			if (activePart.getObject() instanceof IOutlinePageProvider) {
+				pageContext = activePart.getContext().createChild();
+				Composite comp = new Composite(parent, SWT.NONE);
+				comp.setLayout(new FillLayout());
+				pageControl = comp;
+				pageContext.set(Composite.class, comp);
+				ContextInjectionFactory.make(((IOutlinePageProvider) activePart
+						.getObject()).getOutlineClass(), pageContext);
+			} else {
+				oldPageContext = null;
+				oldPageControl = null;
+			}
+		} else {
+			Label label = new Label(parent, SWT.NONE);
+			label.setText("No outline available");
+			pageControl = label;
+		}
+		
+		// Dispose afterwards which helps potential image resource pooling
+		if (oldPageContext != null) {
+			oldPageContext.dispose();
+		}
+
+		if (oldPageControl != null) {
+			oldPageControl.dispose();
+		}
+		
+		parent.layout(true, true);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.outline/xmi/fragment.e4xmi
new file mode 100644
index 0000000..56ad614
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/xmi/fragment.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_glJTgHijEd-QLpUkCzu7EA">
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_ocBJIHijEd-TPIFsLcQOCg" featurename="children" parentElementId="org.eclipse.e4.secondaryNavigationStack">
+    <elements xsi:type="basic:Part" xmi:id="_tcCtcHijEd-TPIFsLcQOCg" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.outline/org.eclipse.e4.demo.simpleide.outline.internal.OutlineView" label="Outline" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif"/>
+  </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/.classpath b/examples/org.eclipse.e4.demo.simpleide.services/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/.project b/examples/org.eclipse.e4.demo.simpleide.services/.project
new file mode 100644
index 0000000..763561b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.services</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.services/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..597e724
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon May 17 18:38:37 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.services/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8759926
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Services
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.services
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.demo.simpleide.services
+Require-Bundle: org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0"
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/build.properties b/examples/org.eclipse.e4.demo.simpleide.services/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/AbstractBundleImageProvider.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/AbstractBundleImageProvider.java
new file mode 100644
index 0000000..b4655e6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/AbstractBundleImageProvider.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.Bundle;
+
+public abstract class AbstractBundleImageProvider implements IImageProviderService {
+	
+	public final String[] getImageKeys() {
+		return getImageMap().values().toArray(new String[0]);
+	}
+
+	public final InputStream getImageData(String imageKey) throws CoreException {
+		Map<String, String> map = getImageMap();
+		
+		if( map.containsKey(imageKey) ) {
+			return getStream(imageKey, map.get(imageKey));
+		}
+		
+		throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "The image key '"+imageKey+"' is unknown."));
+	}
+
+	private InputStream getStream(String imageKey, String path) throws CoreException {
+		URL url = FileLocator.find(getBundle(imageKey), new Path(path), null);
+		if( url != null ) {
+			try {
+				return url.openStream();
+			} catch (IOException e) {
+				throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "Unable to open stream to URL '"+url+"'"));
+			}
+		}
+		throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "The path '"+path+"' is unknown."));
+	}
+	
+	
+	
+	protected abstract Map<String, String> getImageMap();
+	protected abstract Bundle getBundle(String imageKey);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IExportResourceService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IExportResourceService.java
new file mode 100644
index 0000000..654fddc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IExportResourceService.java
@@ -0,0 +1,14 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.swt.widgets.Shell;
+
+public interface IExportResourceService {
+	public String getCategoryName();
+	
+	public String getIconURI();
+	
+	public String getLabel();
+	
+	public void exportResource(Shell shell, IEclipseContext context);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageProviderService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageProviderService.java
new file mode 100644
index 0000000..4f79c57
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageProviderService.java
@@ -0,0 +1,10 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+
+public interface IImageProviderService {
+//	public String[] getImageKeys();
+	public InputStream getImageData(String imageKey) throws CoreException;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageService.java
new file mode 100644
index 0000000..3e5517d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageService.java
@@ -0,0 +1,40 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+
+public interface IImageService {
+	public interface IImagePool {
+		public Image getImage(String imageKey) throws CoreException;
+		public Image getImageUnchecked(String imageKey);
+	}
+
+	public interface IDiposeableImagePool extends IImagePool {
+		public void dispose();
+	}
+
+	public interface IPooledImage {
+		public Image getImage();
+
+		public void dipose();
+	}
+
+	public Image getImage(String imageKey)
+			throws CoreException;
+
+	public IPooledImage getPooledImage(String imageKey)
+			throws CoreException;
+
+	public IDiposeableImagePool getPool();
+
+	/**
+	 * Get an image pool which is connected to a control and gets disposed when
+	 * the control it is connected to is disposed
+	 * 
+	 * @param control
+	 *            the control it is connected to
+	 * @return a new pool connected to the control
+	 */
+	public IImagePool getControlPool(Control control);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImportResourceService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImportResourceService.java
new file mode 100644
index 0000000..eae79c8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImportResourceService.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.swt.widgets.Shell;
+
+public interface IImportResourceService {
+	public String getCategoryName();
+	public String getIconURI();
+	public String getLabel();
+	public void importResource(Shell shell, IEclipseContext context);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/INLSLookupFactoryService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/INLSLookupFactoryService.java
new file mode 100644
index 0000000..39e9ec1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/INLSLookupFactoryService.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+public interface INLSLookupFactoryService {
+	/**
+	 * Creates a lookup which adapts dynamically to the current language stored
+	 * in {@link Locale#getDefault()}
+	 * 
+	 * @param <L>
+	 *            the interface type
+	 * @param clazz
+	 *            the interface type
+	 * @return the lookup instance
+	 */
+	public <L> L createDynamicNLSLookup(Class<L> clazz);
+
+	/**
+	 * Create a lookup which uses the give locale for lookups in dependently
+	 * from the current default locale
+	 * 
+	 * @param <L>
+	 *            the interface type
+	 * @param clazz
+	 *            the interface type
+	 * @param locale
+	 *            the locale
+	 * @return the lookup instance
+	 */
+	public <L> L createNLSLookup(Class<L> clazz, Locale locale);
+
+	/**
+	 * Create a lookup which uses the give locale for lookups in dependently
+	 * from the current default locale.
+	 * <p>
+	 * This method has the same results as
+	 * <code>createNLSLookup(My.class, Locale.getDefault())</code>
+	 * </p>
+	 * 
+	 * @param <L>
+	 *            the interface type
+	 * @param clazz
+	 *            the interface type
+	 * @return the lookup instance
+	 */
+	public <L> L createNLSLookup(Class<L> clazz);
+
+	/**
+	 * Translate a value using one of the registered translation services
+	 * 
+	 * @param category
+	 *            the category to identify the service
+	 * @param key
+	 *            the key
+	 * @param args
+	 *            the arguments for substitution
+	 * @return the string in the current default locale
+	 */
+	public String translate(String category, String key, Object... args);
+
+	/**
+	 * Translate a value using one of the registered translation services
+	 * 
+	 * @param category
+	 *            the category to identify the service
+	 * @param key
+	 *            the key
+	 * @param locale
+	 *            the locale to use
+	 * @param args
+	 *            the arguments for substitution
+	 * @return the translated string
+	 */
+	public String translate(String category, String key, Locale locale,
+			Object... args);
+
+	/**
+	 * Configures the cacheing of the Lookup class
+	 */
+	@Target(ElementType.TYPE)
+	public @interface Cache {
+
+	}
+
+	/**
+	 * Marks the value to be looked up through the given service class
+	 */
+	@Target(ElementType.TYPE)
+	public @interface OSGiService {
+		String serviceId();
+	}
+
+	@Target(ElementType.METHOD)
+	public @interface Key {
+		String category() default "N/A";
+
+		String key();
+	}
+
+	public interface ITranslationService {
+		public String translate(String category, String key, Locale locale);
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IProjectService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IProjectService.java
new file mode 100644
index 0000000..33f7e76
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IProjectService.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.swt.widgets.Shell;
+
+public interface IProjectService {
+	public String getIconURI();
+	public String getLabel();
+	public void createProject(Shell shell, IWorkspace workspace, StatusReporter statusReporter, Logger logger, IProgressMonitor monitor, String projectName);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/ImageService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/ImageService.java
new file mode 100644
index 0000000..3d42f40
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/ImageService.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.services.IImageProviderService;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.e4.demo.simpleide.services.OSGiUtil;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+public class ImageService implements IImageService {
+	
+	public static class PooledImage implements IPooledImage {
+		private int count;
+		private Image image;
+		private String imageKey;
+		private ImageService imageService;
+		
+		PooledImage(ImageService imageService, String imageKey, Image image) {
+			this.count = 1;
+			this.image = image;
+			this.imageKey = imageKey;
+		}
+
+		public Image getImage() {
+			return image;
+		}
+
+		public void dipose() {
+			this.count--;
+			if( this.count == 0 ) {
+				image.dispose();
+				imageService.removePooledImage(this);
+				image = null;
+				imageService = null;
+				imageKey = null;
+			}
+		}
+	}
+	
+	private static class ImagePool implements IDiposeableImagePool {
+		private ImageService imageService;
+		private List<IPooledImage> pooledImages = new ArrayList<IPooledImage>();
+		
+		public ImagePool(ImageService imageService) {
+			this.imageService = imageService;
+		}
+		
+		public Image getImage(String imageKey) throws CoreException {
+			if( imageService == null ) {
+				throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "The pool is disposed"));
+			}
+			IPooledImage image = imageService.getPooledImage(imageKey);
+			pooledImages.add(image);
+			return image.getImage();
+		}
+		
+		public Image getImageUnchecked(String imageKey) {
+			try {
+				return getImage(imageKey);
+			} catch (CoreException e) {
+				throw new RuntimeException(e);
+			}
+		}
+
+		public void dispose() {
+			for( IPooledImage img : pooledImages ) {
+				img.dipose();
+			}
+			imageService = null;
+			pooledImages = null;
+		}
+	}
+	
+	private Map<String, IImageProviderService> key2providers = new HashMap<String, IImageProviderService>();
+	private Map<String, PooledImage> imagePool = new HashMap<String, ImageService.PooledImage>();
+	
+	private Logger logger;
+	private Display display;
+	
+	@Inject
+	public ImageService(Logger logger, Display display) {
+		this.logger = logger;
+		this.display = display;
+	}
+	
+	public void addImageProvider(IImageProviderService imageProvider, Collection<String> imageKeys) {
+		synchronized (key2providers) {
+			for( String s : imageKeys ) {
+				if( ! key2providers.containsKey(s) ) {
+					key2providers.put(s, imageProvider);
+				} else {
+					IImageProviderService tmp = key2providers.get(s);
+					logger.error("Can not register imagekey '"+s+"' for "+imageProvider+" ("+OSGiUtil.getBundleName(imageProvider.getClass())+") because is already connected to " + tmp + " ("+OSGiUtil.getBundleName(tmp.getClass())+")");
+				}
+			}
+		}
+	}
+	
+	public void removeImageProvider(IImageProviderService imageProvider) {
+		synchronized (key2providers) {
+			Iterator<Entry<String, IImageProviderService>> it = key2providers.entrySet().iterator();
+			while( it.hasNext() ) {
+				if( it.next().getValue() == imageProvider ) {
+					it.remove();
+				}
+			}
+		}
+	}
+	
+	public Image getImage(String imageKey) throws CoreException {
+		IImageProviderService provider = key2providers.get(imageKey);
+		if( provider != null ) {
+			InputStream stream = provider.getImageData(imageKey);
+			return new Image(display, stream);
+		} else {
+			throw new IllegalArgumentException("There's no image provider known for '"+imageKey+"'.");
+		}
+	} 
+
+	public IPooledImage getPooledImage(String imageKey) throws CoreException {
+		PooledImage image = imagePool.get(imageKey);
+		
+		if( image != null ) {
+			image.count++;
+			
+		} else {
+			image = new PooledImage(this,imageKey,getImage(imageKey));
+		}
+		
+		return image;
+	}
+
+	void removePooledImage(PooledImage image) {
+		imagePool.remove(image.imageKey);
+	}
+	
+	public IDiposeableImagePool getPool() {
+		return new ImagePool(this);
+	}
+
+	public IImagePool getControlPool(Control control) {
+		final IDiposeableImagePool pool = getPool();
+		control.addDisposeListener(new DisposeListener() {
+			
+			public void widgetDisposed(DisposeEvent e) {
+				pool.dispose();
+			}
+		});
+		return pool;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/OSGiUtil.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/OSGiUtil.java
new file mode 100644
index 0000000..aa446c0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/OSGiUtil.java
@@ -0,0 +1,9 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.osgi.framework.FrameworkUtil;
+
+public class OSGiUtil {
+	public static final String getBundleName(Class<?> clazz) {
+		return FrameworkUtil.getBundle(clazz).getSymbolicName();
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/.classpath b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/.project b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.project
new file mode 100644
index 0000000..593e476
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide.sharedimages</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d828ba6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sun May 23 10:56:46 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.sharedimages/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1a3e57a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Sharedimages
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.sharedimages
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0"
+Service-Component: OSGI-INF/sharedImageProviderService.xml
+Export-Package: org.eclipse.e4.demo.simpleide.sharedimages
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/OSGI-INF/sharedImageProviderService.xml b/examples/org.eclipse.e4.demo.simpleide.sharedimages/OSGI-INF/sharedImageProviderService.xml
new file mode 100644
index 0000000..acdffb4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/OSGI-INF/sharedImageProviderService.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.sharedimages.sharedImageProviderService">
+   <implementation class="org.eclipse.e4.demo.simpleide.sharedimages.internal.SharedImageProviderService"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.simpleide.services.IImageProviderService"/>
+   </service>
+   <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_ETOOL_HOME_NAV"/>
+   <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_BACK"/>
+   <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_BACK_DISABLED"/>
+   <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_FORWARD"/>
+   <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_FORWARD_DISABLED"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/build.properties b/examples/org.eclipse.e4.demo.simpleide.sharedimages/build.properties
new file mode 100644
index 0000000..729ad41
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               OSGI-INF/sharedImageProviderService.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_disabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_disabled.gif
new file mode 100644
index 0000000..2972ff5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_disabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_enabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_enabled.gif
new file mode 100644
index 0000000..4fb4150
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_enabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_disabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_disabled.gif
new file mode 100644
index 0000000..319fe8d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_disabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_enabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_enabled.gif
new file mode 100644
index 0000000..e2f8c3e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_enabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/home_nav_enabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/home_nav_enabled.gif
new file mode 100644
index 0000000..4472e8c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/home_nav_enabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/SharedImageKeys.java b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/SharedImageKeys.java
new file mode 100644
index 0000000..ec5e678
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/SharedImageKeys.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.sharedimages;
+
+import org.eclipse.e4.demo.simpleide.sharedimages.internal.SharedImageProviderService;
+
+public class SharedImageKeys {
+	private static final String BUNDLE_ID = SharedImageProviderService.BUNDLE.getSymbolicName();
+	
+	/**
+     * Identifies the home image in the enabled state.
+     * @since 3.4
+     */
+	public final static String IMG_TOOL_HOME_NAV = BUNDLE_ID + ".IMG_ETOOL_HOME_NAV"; //$NON-NLS-1$
+    
+	/**
+     * Identifies the back image in the enabled state.
+     */
+    public final static String IMG_TOOL_BACK = BUNDLE_ID + ".IMG_TOOL_BACK"; //$NON-NLS-1$
+
+    /**
+     * Identifies the back image in the disabled state.
+     */
+    public final static String IMG_TOOL_BACK_DISABLED = BUNDLE_ID + ".IMG_TOOL_BACK_DISABLED"; //$NON-NLS-1$
+
+    /**
+     * Identifies the forward image in the enabled state.
+     */
+    public final static String IMG_TOOL_FORWARD = BUNDLE_ID + ".IMG_TOOL_FORWARD"; //$NON-NLS-1$
+    
+    /**
+     * Identifies the forward image in the disabled state.
+     */
+    public final static String IMG_TOOL_FORWARD_DISABLED = BUNDLE_ID + ".IMG_TOOL_FORWARD_DISABLED"; //$NON-NLS-1$
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/internal/SharedImageProviderService.java b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/internal/SharedImageProviderService.java
new file mode 100644
index 0000000..c37c89a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/internal/SharedImageProviderService.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.sharedimages.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.e4.demo.simpleide.services.AbstractBundleImageProvider;
+import org.eclipse.e4.demo.simpleide.sharedimages.SharedImageKeys;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class SharedImageProviderService extends AbstractBundleImageProvider {
+	public static final Bundle BUNDLE = FrameworkUtil.getBundle(SharedImageKeys.class);
+	
+	private static final Map<String, String> IMAGEMAP = Collections.unmodifiableMap(new HashMap<String, String>() {
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = 1L;
+
+		{
+			put(SharedImageKeys.IMG_TOOL_HOME_NAV, "/icons/home_nav_enabled.gif");
+			put(SharedImageKeys.IMG_TOOL_BACK, "/icons/backward_nav_enabled.gif");
+			put(SharedImageKeys.IMG_TOOL_BACK_DISABLED, "/icons/backward_nav_disabled.gif");
+			put(SharedImageKeys.IMG_TOOL_FORWARD, "/icons/forward_nav_enabled.gif");
+			put(SharedImageKeys.IMG_TOOL_FORWARD_DISABLED, "/icons/forward_nav_disabled.gif");
+		}
+	});
+	
+
+	@Override
+	protected Map<String, String> getImageMap() {
+		return IMAGEMAP;
+	}
+
+	@Override
+	protected Bundle getBundle(String imageKey) {
+		return BUNDLE;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/.classpath b/examples/org.eclipse.e4.demo.simpleide/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide/.project b/examples/org.eclipse.e4.demo.simpleide/.project
new file mode 100644
index 0000000..7c77748
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.simpleide</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ds.core.builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..588d23f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Mon May 24 23:37:20 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..5545bd2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:06:45 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide/Application.e4xmi b/examples/org.eclipse.e4.demo.simpleide/Application.e4xmi
new file mode 100644
index 0000000..7975b1c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/Application.e4xmi
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="ASCII"?>
+<simpleide:SimpleIDEApplication xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_r5eKcGAYEd-Bb9ra7AA28Q" elementId="app.simpleide" bindingContexts="_ui554GEgEd-A9truh9jvIg">
+  <children xsi:type="basic:TrimmedWindow" xmi:id="_tMEPMGAiEd-E_N65-FXwgA" elementId="simpleide.mainwindow" label="Simple e4 IDE" width="800" height="600">
+    <children xsi:type="advanced:PerspectiveStack" xmi:id="_NpAUQGAmEd-c1dfOhrP7Ww" elementId="">
+      <children xsi:type="advanced:Perspective" xmi:id="_TrpzMGAmEd-c1dfOhrP7Ww" elementId="simpleide.perspective.default" label="Default Perspective" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/application_split.png">
+        <children xsi:type="basic:PartSashContainer" xmi:id="_o38KwGAmEd-c1dfOhrP7Ww" horizontal="true">
+          <children xsi:type="basic:PartStack" xmi:id="_y6yIsGAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.primaryNavigationStack">
+            <tags>org.eclipse.e4.primaryNavigationStack</tags>
+          </children>
+          <children xsi:type="basic:PartSashContainer" xmi:id="_2Cm1QGAmEd-c1dfOhrP7Ww">
+            <children xsi:type="basic:PartSashContainer" xmi:id="_3ddpsGAmEd-c1dfOhrP7Ww" horizontal="true">
+              <children xsi:type="basic:PartStack" xmi:id="_8XqS0GAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.primaryDataStack">
+                <tags>org.eclipse.e4.primaryDataStack</tags>
+              </children>
+              <children xsi:type="basic:PartStack" xmi:id="_9JVAUGAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.secondaryNavigationStack">
+                <tags>org.eclipse.e4.secondaryNavigationStack</tags>
+              </children>
+            </children>
+            <children xsi:type="basic:PartStack" xmi:id="_64QVkGAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.secondaryDataStack">
+              <tags>org.eclipse.e4.secondaryDataStack</tags>
+            </children>
+          </children>
+        </children>
+      </children>
+    </children>
+    <variables>outlinepage</variables>
+    <variables>resourceselection</variables>
+    <mainMenu xmi:id="_yobKMGAiEd-E_N65-FXwgA" elementId="simpleide.mainmenu">
+      <children xsi:type="menu:Menu" xmi:id="_0BkucGAiEd-E_N65-FXwgA" elementId="simpleide.mainmenu.file" label="File">
+        <children xsi:type="menu:Menu" xmi:id="_sErgoGAzEd-_KuNHePH0xw" elementId="simpleide.mainmenu.file.new" label="New">
+          <children xsi:type="menu:HandledMenuItem" xmi:id="_hC0PYGHYEd-_Y6o4fctqsw" label="Project ..." iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif" command="_CWMKAGHYEd-_Y6o4fctqsw"/>
+          <children xsi:type="menu:MenuSeparator" xmi:id="_oqi1wGHYEd-_Y6o4fctqsw"/>
+          <children xsi:type="menu:HandledMenuItem" xmi:id="_pbntYGHYEd-_Y6o4fctqsw" label="Text File ..." iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif" command="_F3JIQGHYEd-_Y6o4fctqsw"/>
+          <children xsi:type="menu:HandledMenuItem" xmi:id="_wkGzAGHYEd-_Y6o4fctqsw" label="Folder ..." iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif" command="_IERuMGHYEd-_Y6o4fctqsw"/>
+          <children xsi:type="menu:MenuSeparator" xmi:id="_5FzuUGHYEd-_Y6o4fctqsw"/>
+        </children>
+        <children xsi:type="menu:MenuSeparator" xmi:id="_NHvfwGEiEd-A9truh9jvIg"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_OxUFoGEiEd-A9truh9jvIg" label="Save All" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png" command="_kpAnIGEhEd-A9truh9jvIg"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_mydxgGEiEd-A9truh9jvIg" label="Save" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk.png" command="_tl9UAGEhEd-A9truh9jvIg"/>
+        <children xsi:type="menu:MenuSeparator" xmi:id="_ukxQMGEiEd-A9truh9jvIg"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_7kftUGAiEd-E_N65-FXwgA" label="Exit" command="_oIK3gGAiEd-E_N65-FXwgA"/>
+      </children>
+      <children xsi:type="menu:Menu" xmi:id="_WbMXYEjUEd-v7fhjaiz65w" elementId="_WbMXYEjUEd-v7fhjaiz65w" label="Window">
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_UW9TUPr3Ed6gmo7caOx120" elementId="showView" label="Show &amp;View" command="org.eclipse.ui.views.showView"/>
+      </children>
+    </mainMenu>
+    <trimBars xmi:id="_XAea0GGjEd-_qNzu9_D5ug" elementId="">
+      <children xsi:type="menu:ToolBar" xmi:id="_bf9d4GGjEd-_qNzu9_D5ug" elementId="app.simpleide.toolbar">
+        <children xsi:type="menu:HandledToolItem" xmi:id="_dBds4GGjEd-_qNzu9_D5ug" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk.png" command="_tl9UAGEhEd-A9truh9jvIg"/>
+        <children xsi:type="menu:HandledToolItem" xmi:id="_ioN6AGGjEd-_qNzu9_D5ug" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png" command="_kpAnIGEhEd-A9truh9jvIg"/>
+      </children>
+    </trimBars>
+  </children>
+  <variables>org.eclipse.e4.demo.simpleide.services.IImageService</variables>
+  <handlers xmi:id="_jXCDwGAiEd-E_N65-FXwgA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.ExitHandler" command="_oIK3gGAiEd-E_N65-FXwgA"/>
+  <handlers xmi:id="_pj_6cGEhEd-A9truh9jvIg" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.SaveAllHandler" command="_kpAnIGEhEd-A9truh9jvIg"/>
+  <handlers xmi:id="_w0lzMGEhEd-A9truh9jvIg" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.SaveHandler" command="_tl9UAGEhEd-A9truh9jvIg"/>
+  <handlers xmi:id="_BTglAGHYEd-_Y6o4fctqsw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.NewProjectDialogHandler" command="_CWMKAGHYEd-_Y6o4fctqsw"/>
+  <handlers xmi:id="_T8XWgGHYEd-_Y6o4fctqsw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.NewTextFileDialogHandler" command="_F3JIQGHYEd-_Y6o4fctqsw"/>
+  <handlers xmi:id="_WjZDIGHYEd-_Y6o4fctqsw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.NewFolderDialogHandler" command="_IERuMGHYEd-_Y6o4fctqsw"/>
+  <handlers xmi:id="_eTBRgAFSEd-Z8rQksLwRYx" elementId="org.eclipse.ui.showViewHandler" contributionURI="bundleclass://org.eclipse.e4.ui.workbench.swt/org.eclipse.e4.ui.internal.workbench.swt.handlers.ShowViewHandler" command="org.eclipse.ui.views.showView"/>
+  <handlers xmi:id="_GuF_8GceEd-UeOvBc5sIBQ" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.SwitchThemeHandler" command="_VAYokGcYEd-XPd4cWNb-1Q"/>
+  <bindingTables xmi:id="_bFtE4GEhEd-A9truh9jvIg" bindingContext="_ui554GEgEd-A9truh9jvIg">
+    <bindings xmi:id="_fW-s0GEhEd-A9truh9jvIg" keySequence="M1+Q" command="_oIK3gGAiEd-E_N65-FXwgA"/>
+    <bindings xmi:id="_z1SkEGEhEd-A9truh9jvIg" keySequence="M1+M2+S" command="_kpAnIGEhEd-A9truh9jvIg"/>
+    <bindings xmi:id="_AcDQQGEiEd-A9truh9jvIg" keySequence="M1+S" command="_tl9UAGEhEd-A9truh9jvIg"/>
+    <bindings xmi:id="_tDFjkEjPEd-XR8_8rlW1bQ" elementId="_tDFjkEjPEd-XR9_8rlW1bQ" keySequence="CTRL+C" command="org.eclipse.ui.edit.copy"/>
+  </bindingTables>
+  <rootContext xmi:id="_ui554GEgEd-A9truh9jvIg" elementId="org.eclipse.ui.contexts.dialogAndWindow" name="In Dialogs And Windows" description="">
+    <children xmi:id="_LB_JoGEhEd-A9truh9jvIg" elementId="org.eclipse.ui.contexts.window" name="In Windows" description=""/>
+    <children xmi:id="_ULwKgGEhEd-A9truh9jvIg" elementId="org.eclipse.ui.contexts.dialog" name="In Dialogs" description=""/>
+  </rootContext>
+  <commands xmi:id="_oIK3gGAiEd-E_N65-FXwgA" elementId="simpleide.command.exit" commandName="Exit IDE"/>
+  <commands xmi:id="_kpAnIGEhEd-A9truh9jvIg" elementId="simpleide.command.saveall" commandName="Save All"/>
+  <commands xmi:id="_tl9UAGEhEd-A9truh9jvIg" elementId="simpleide.command.save" commandName="Save"/>
+  <commands xmi:id="_CWMKAGHYEd-_Y6o4fctqsw" elementId="simpleide.command.newproject" commandName="New Project Command"/>
+  <commands xmi:id="_F3JIQGHYEd-_Y6o4fctqsw" elementId="simpleide.command.newtxtfile" commandName="New Text File Command"/>
+  <commands xmi:id="_IERuMGHYEd-_Y6o4fctqsw" elementId="simpleide.command.newfolder" commandName="New Folder Command"/>
+  <commands xmi:id="org.eclipse.ui.views.showView" elementId="org.eclipse.ui.views.showView" commandName="Show View">
+    <parameters xmi:id="_oRr6EAFSEd-Z8rQksLwRYy" elementId="org.eclipse.ui.views.showView.viewId" name="View"/>
+  </commands>
+  <commands xmi:id="org.eclipse.ui.edit.copy" elementId="org.eclipse.ui.edit.copy" commandName="Copy"/>
+  <commands xmi:id="_VAYokGcYEd-XPd4cWNb-1Q" elementId="simpleide.command.switchtheme" commandName="Switch Theme">
+    <parameters xmi:id="_jQ1PYGcYEd-XPd4cWNb-1Q" elementId="simpleide.command.switchtheme.themeid" name="Theme Id" typeId="" optional="false"/>
+  </commands>
+  <addons xmi:id="_XGB3wPZlEd-XstlTZ6nTXg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
+  <addons xmi:id="_XGB3wPZlEd-XstlTZ6nTXh" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
+  <addons xmi:id="_XGB3wPZlEd-XstlTZ6nTXi" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>
+  <addons xmi:id="_LK0NgPZmEd-XstlTZ6nTXj" elementId="org.eclipse.e4.ui.workbench.commands.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon"/>
+  <addons xmi:id="_LK0NgPZmEd-XstlTZ6nTXk" elementId="org.eclipse.e4.ui.workbench.contexts.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon"/>
+  <addons xmi:id="_LK0NgPZmEd-XstlTZ6nTXl" elementId="org.eclipse.e4.ui.workbench.bindings.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench.swt/org.eclipse.e4.ui.workbench.swt.util.BindingProcessingAddon"/>
+</simpleide:SimpleIDEApplication>
diff --git a/examples/org.eclipse.e4.demo.simpleide/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d23c687
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simpleide
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.ui.workbench.swt;bundle-version="0.9.1",
+ org.eclipse.equinox.app;bundle-version="1.3.0",
+ org.eclipse.e4.ui.css.swt.theme;bundle-version="0.9.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.core.jobs;bundle-version="3.5.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.core.filesystem;bundle-version="1.3.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0"
+Service-Component: OSGI-INF/serviceRegistryComponent.xml, OSGI-INF/defaultProjectService.xml, OSGI-INF/eclipseProjectImporterService.xml, OSGI-INF/imageServiceFunction.xml, OSGI-INF/nlsLookupFactoryService.xml
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/defaultProjectService.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/defaultProjectService.xml
new file mode 100644
index 0000000..c7bd13d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/defaultProjectService.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.simpleide.defaultcreator">
+   <implementation class="org.eclipse.e4.demo.simpleide.internal.DefaultProjectService"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.simpleide.services.IProjectService"/>
+   </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/eclipseProjectImporterService.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/eclipseProjectImporterService.xml
new file mode 100644
index 0000000..22b57ca
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/eclipseProjectImporterService.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.eclipseProjectImporterService">
+   <implementation class="org.eclipse.e4.demo.simpleide.internal.EclipseProjectImportService"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.simpleide.services.IImportResourceService"/>
+   </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/imageServiceFunction.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/imageServiceFunction.xml
new file mode 100644
index 0000000..e3bb17b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/imageServiceFunction.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.imageServiceFunction">
+   <implementation class="org.eclipse.e4.demo.simpleide.internal.ImageServiceFunction"/>
+   <service>
+      <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+   </service>
+   <property name="service.context.key" type="String" value="org.eclipse.e4.demo.simpleide.services.IImageService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/nlsLookupFactoryService.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/nlsLookupFactoryService.xml
new file mode 100644
index 0000000..29eac63
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/nlsLookupFactoryService.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.nlsLookupFactoryService">
+   <implementation class="org.eclipse.e4.demo.simpleide.internal.NLSLookupFactoryServiceImpl"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService"/>
+   </service>
+   <reference bind="addTranslationService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService$ITranslationService" name="INLSLookupFactoryService$ITranslationService" policy="dynamic" unbind="removeTranslationService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/serviceRegistryComponent.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/serviceRegistryComponent.xml
new file mode 100644
index 0000000..5d2a026
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/serviceRegistryComponent.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="false" name="org.eclipse.e4.demo.simpleide.projectCreatorComponent">
+   <implementation class="org.eclipse.e4.demo.simpleide.internal.ServiceRegistryComponent"/>
+   <service>
+      <provide interface="org.eclipse.e4.demo.simpleide.internal.ServiceRegistryComponent"/>
+   </service>
+   <reference bind="addProjectService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.IProjectService" name="IProjectService" policy="dynamic" unbind="removeProjectService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/SimpleIDE.product b/examples/org.eclipse.e4.demo.simpleide/SimpleIDE.product
new file mode 100644
index 0000000..a7a1d4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/SimpleIDE.product
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="SimpleIDE" id="org.eclipse.e4.demo.simpleide.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" useFeatures="false" includeLaunchers="true">
+
+   <configIni use="default">
+   </configIni>
+
+   <launcherArgs>
+      <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+   </launcherArgs>
+
+   <plugins>
+      <plugin id="com.ibm.icu"/>
+      <plugin id="javax.annotation"/>
+      <plugin id="javax.inject"/>
+      <plugin id="org.apache.batik.css"/>
+      <plugin id="org.apache.batik.util"/>
+      <plugin id="org.apache.batik.util.gui"/>
+      <plugin id="org.apache.commons.beanutils" fragment=""/>
+      <plugin id="org.apache.commons.logging"/>
+      <plugin id="org.eclipse.core.commands"/>
+      <plugin id="org.eclipse.core.contenttype"/>
+      <plugin id="org.eclipse.core.databinding"/>
+      <plugin id="org.eclipse.core.databinding.observable"/>
+      <plugin id="org.eclipse.core.databinding.property"/>
+      <plugin id="org.eclipse.core.expressions"/>
+      <plugin id="org.eclipse.core.filesystem"/>
+      <plugin id="org.eclipse.core.filesystem.linux.x86" fragment="true"/>
+      <plugin id="org.eclipse.core.filesystem.macosx" fragment="true"/>
+      <plugin id="org.eclipse.core.jobs"/>
+      <plugin id="org.eclipse.core.resources"/>
+      <plugin id="org.eclipse.core.runtime"/>
+      <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
+      <plugin id="org.eclipse.e4.core.commands"/>
+      <plugin id="org.eclipse.e4.core.contexts"/>
+      <plugin id="org.eclipse.e4.core.di"/>
+      <plugin id="org.eclipse.e4.core.di.extensions"/>
+      <plugin id="org.eclipse.e4.core.services"/>
+      <plugin id="org.eclipse.e4.demo.simpleide"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.e4editor"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.editor"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.editor.text"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.iconview"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.jdt"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.model"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.navigator"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.outline"/>
+      <plugin id="org.eclipse.e4.demo.simpleide.services"/>
+      <plugin id="org.eclipse.e4.demo.tools.simpleide"/>
+      <plugin id="org.eclipse.e4.tools.emf.ui"/>
+      <plugin id="org.eclipse.e4.ui.bindings"/>
+      <plugin id="org.eclipse.e4.ui.css.core"/>
+      <plugin id="org.eclipse.e4.ui.css.swt"/>
+      <plugin id="org.eclipse.e4.ui.css.swt.theme"/>
+      <plugin id="org.eclipse.e4.ui.di"/>
+      <plugin id="org.eclipse.e4.ui.model.workbench"/>
+      <plugin id="org.eclipse.e4.ui.model.workbench.edit"/>
+      <plugin id="org.eclipse.e4.ui.services"/>
+      <plugin id="org.eclipse.e4.ui.workbench"/>
+      <plugin id="org.eclipse.e4.ui.workbench.renderers.swt"/>
+      <plugin id="org.eclipse.e4.ui.workbench.swt"/>
+      <plugin id="org.eclipse.e4.ui.workbench3"/>
+      <plugin id="org.eclipse.emf.common"/>
+      <plugin id="org.eclipse.emf.databinding"/>
+      <plugin id="org.eclipse.emf.databinding.edit"/>
+      <plugin id="org.eclipse.emf.ecore"/>
+      <plugin id="org.eclipse.emf.ecore.change"/>
+      <plugin id="org.eclipse.emf.ecore.xmi"/>
+      <plugin id="org.eclipse.emf.edit"/>
+      <plugin id="org.eclipse.equinox.app"/>
+      <plugin id="org.eclipse.equinox.common"/>
+      <plugin id="org.eclipse.equinox.concurrent"/>
+      <plugin id="org.eclipse.equinox.ds"/>
+      <plugin id="org.eclipse.equinox.event"/>
+      <plugin id="org.eclipse.equinox.preferences"/>
+      <plugin id="org.eclipse.equinox.registry"/>
+      <plugin id="org.eclipse.equinox.util"/>
+      <plugin id="org.eclipse.jdt.compiler.apt" fragment="true"/>
+      <plugin id="org.eclipse.jdt.compiler.tool" fragment="true"/>
+      <plugin id="org.eclipse.jdt.core"/>
+      <plugin id="org.eclipse.jface"/>
+      <plugin id="org.eclipse.jface.databinding"/>
+      <plugin id="org.eclipse.jface.text"/>
+      <plugin id="org.eclipse.nebula.widgets.gallery"/>
+      <plugin id="org.eclipse.osgi"/>
+      <plugin id="org.eclipse.osgi.services"/>
+      <plugin id="org.eclipse.swt"/>
+      <plugin id="org.eclipse.swt.cocoa.macosx.x86_64" fragment="true"/>
+      <plugin id="org.eclipse.swt.gtk.linux.x86" fragment="true"/>
+      <plugin id="org.eclipse.text"/>
+      <plugin id="org.w3c.css.sac"/>
+      <plugin id="org.w3c.dom.smil"/>
+      <plugin id="org.w3c.dom.svg"/>
+   </plugins>
+
+
+</product>
diff --git a/examples/org.eclipse.e4.demo.simpleide/build.properties b/examples/org.eclipse.e4.demo.simpleide/build.properties
new file mode 100644
index 0000000..f9ec2aa
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/build.properties
@@ -0,0 +1,11 @@
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               Application.e4xmi,\
+               css/,\
+               icons/,\
+               OSGI-INF/,\
+               OSGI-INF/imageServiceFunction.xml,\
+               OSGI-INF/nlsLookupFactoryService.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default.css
new file mode 100644
index 0000000..839cf31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default.css
@@ -0,0 +1,28 @@
+
+.MWindow {
+    background-color:  #EEF2F7 #DEEBF3 100%;
+}
+
+.MTrimmedWindow {  
+    margin-top: 12px;
+    margin-bottom: 2px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+.MPartStack {
+    tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+    unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+    outer-keyline-color: #FFFFFF;
+	inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar  {
+    background-image:  url(./winXPBlue.PNG);	
+}
+
+.MPartStack.active {
+	unselected-tabs-color: #CEDEF4 #D2E2F9 #FFFFFF 100% 100%;
+    outer-keyline-color: #C3D0E9;
+	inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_gtk.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_gtk.css
new file mode 100644
index 0000000..d54b392
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_gtk.css
@@ -0,0 +1,25 @@
+
+.MTrimmedWindow { 
+    background-color: #E2E2E2; 
+    margin-top: 12px;
+    margin-bottom: 2px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+.MPartStack {
+    tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+    unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+    outer-keyline-color: #FFFFFF;
+	inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar  {
+    background-image:  url(./gtkGrey.PNG);	
+}
+
+.MPartStack.active {
+	unselected-tabs-color: #DCDCDC #E1E1E1 #FFFFFF 100% 100%;
+    	outer-keyline-color: #C4C5C1;
+	inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_mac.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_mac.css
new file mode 100644
index 0000000..dbc7c7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_mac.css
@@ -0,0 +1,25 @@
+
+.MTrimmedWindow { 
+    background-color: #F0F0F0 #E5E5E5 100%; 
+    margin-top: 12px;
+    margin-bottom: 2px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+.MPartStack {
+    tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+    unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+    outer-keyline-color: #FFFFFF;
+	inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar  {
+    background-image:  url(./macGrey.PNG);	
+}
+
+.MPartStack.active {
+	unselected-tabs-color: #E2E2E2 #EBEBEC #FFFFFF 100% 100%;
+    	outer-keyline-color: #C4C5C1;
+	inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_win7.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_win7.css
new file mode 100644
index 0000000..7ebcb1d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_win7.css
@@ -0,0 +1,25 @@
+
+.MTrimmedWindow { 
+    background-color: #E6EAF7; 
+    margin-top: 12px;
+    margin-bottom: 2px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+.MPartStack {
+    tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+    unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+    outer-keyline-color: #FFFFFF;
+	inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar  {
+    background-image:  url(./win7.PNG);	
+}
+
+.MPartStack.active {
+	unselected-tabs-color: #F3F9ff #D0DFEE #CEDDED #D2E1F0 #FFFFFF 30% 50% 100% 100%;
+    	outer-keyline-color: #C4C5C1;
+	inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_blu.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_blu.css
new file mode 100644
index 0000000..161b355
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_blu.css
@@ -0,0 +1,24 @@
+
+.MTrimmedWindow { 
+    margin-top: 12px;
+    margin-bottom: 2px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+.MPartStack {
+    tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+    unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+    outer-keyline-color: #FFFFFF;
+	inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar  {
+    background-image:  url(./winXPBlue.PNG);	
+}
+
+.MPartStack.active {
+	unselected-tabs-color: #CEDEF4 #D2E2F9 #FFFFFF 100% 100%;
+    outer-keyline-color: #C3D0E9;
+	inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_olv.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_olv.css
new file mode 100644
index 0000000..7b67f9e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_olv.css
@@ -0,0 +1,25 @@
+
+
+.MTrimmedWindow { 
+    margin-top: 12px;
+    margin-bottom: 2px;
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+.MPartStack {
+    tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+    unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+    outer-keyline-color: #FFFFFF;
+	inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar  {
+    background-image:  url(./winXPOlive.PNG);	
+}
+
+.MPartStack.active {
+	unselected-tabs-color: #E6E3C3 #EDEACA #FFFFFF 100% 100%;
+    outer-keyline-color: #BFCDA4;
+	inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/application_split.png b/examples/org.eclipse.e4.demo.simpleide/icons/application_split.png
new file mode 100644
index 0000000..a91c78a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/application_split.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/gtkGrey.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/gtkGrey.PNG
new file mode 100644
index 0000000..c559dbb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/gtkGrey.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/macGrey.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/macGrey.PNG
new file mode 100644
index 0000000..59075ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/macGrey.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/win7.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/win7.PNG
new file mode 100644
index 0000000..e0f8910
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/win7.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPBlue.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPBlue.PNG
new file mode 100644
index 0000000..57e94e5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPBlue.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPOlive.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPOlive.PNG
new file mode 100644
index 0000000..c745ee1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPOlive.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/disk.png b/examples/org.eclipse.e4.demo.simpleide/icons/disk.png
new file mode 100644
index 0000000..99d532e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/disk.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png b/examples/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png
new file mode 100644
index 0000000..fc5a52f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif b/examples/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif
new file mode 100644
index 0000000..9d05088
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif b/examples/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif
new file mode 100644
index 0000000..310eb18
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif b/examples/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif
new file mode 100644
index 0000000..fbbac0f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newfolder_wiz.png b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newfolder_wiz.png
new file mode 100644
index 0000000..f4861b1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newfolder_wiz.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newprj_wiz.png b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newprj_wiz.png
new file mode 100644
index 0000000..fdff016
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newprj_wiz.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/plugin.xml b/examples/org.eclipse.e4.demo.simpleide/plugin.xml
new file mode 100644
index 0000000..90933fd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/plugin.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.e4.ui.css.swt.theme">
+      <theme
+            basestylesheeturi="css/e4_default.css"
+            id="org.eclipse.e4.demo.simpleide.theme"
+            label="Default Theme">
+      </theme>
+      <theme
+            basestylesheeturi="css/e4_default_gtk.css"
+            id="org.eclipse.e4.demo.simpleide.theme.gtk"
+            label="GTK Theme">
+      </theme>
+      <theme
+            basestylesheeturi="css/e4_default_mac.css"
+            id="org.eclipse.e4.demo.simpleide.theme.mac"
+            label="Mac Theme">
+      </theme>
+      <theme
+            basestylesheeturi="css/e4_default_win7.css"
+            id="org.eclipse.e4.demo.simpleide.theme.win7"
+            label="Win7 Theme">
+      </theme>
+      <theme
+            basestylesheeturi="css/e4_default_winxp_blu.css"
+            id="org.eclipse.e4.demo.simpleide.theme.winxp.blu"
+            label="WinXP Blue Theme">
+      </theme>
+      <theme
+            basestylesheeturi="css/e4_default_winxp_olv.css"
+            id="org.eclipse.e4.demo.simpleide.theme.winxp.olv"
+            label="WinXP Olive Theme">
+      </theme>
+   </extension>
+   <extension
+         id="product"
+         point="org.eclipse.core.runtime.products">
+      <product
+            application="org.eclipse.e4.ui.workbench.swt.E4Application"
+            name="SimpleIDE">
+         <property
+               name="appName"
+               value="SimpleIDE">
+         </property>
+         <property
+               name="applicationXMI"
+               value="org.eclipse.e4.demo.simpleide/Application.e4xmi">
+         </property>
+         <property
+               name="cssTheme"
+               value="org.eclipse.e4.demo.simpleide.theme">
+         </property>
+         <property
+               name="applicationCSSResources"
+               value="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/css/">
+         </property>
+      </product>
+   </extension>
+   <extension
+         id="id1"
+         point="org.eclipse.e4.workbench.model">
+      <processor
+            beforefragment="true"
+            class="org.eclipse.e4.demo.simpleide.internal.ThemeMenuProcessor">
+         <element
+               id="simpleide.mainmenu">
+         </element>
+      </processor>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/ExitHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/ExitHandler.java
new file mode 100644
index 0000000..eb05262
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/ExitHandler.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.workbench.IPresentationEngine;
+
+public class ExitHandler {
+	@Execute
+	public void exitWorkbench(IPresentationEngine engine) {
+		engine.stop();
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.java
new file mode 100644
index 0000000..345ef3c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+public interface Messages {
+	public String NewFolderDialogHandler_ParentFolder();
+
+	public String NewFolderDialogHandler_FolderName();
+
+	public String NewFolderDialogHandler_ShellTitle();
+
+	public String NewFolderDialogHandler_Title();
+
+	public String NewFolderDialogHandler_Message();
+
+	public String NewFolderDialogHandler_ErrorSelectAParentFolder();
+
+	public String NewFolderDialogHandler_ErrorEnterFolderName();
+	
+	public String NewFolderDialogHandler_ErrorFolderCreation();
+
+	public String NewProjectDialogHandler_ShellTitle();
+
+	public String NewProjectDialogHandler_Title();
+
+	public String NewProjectDialogHandler_Message();
+
+	public String NewProjectDialogHandler_Name();
+
+	public String NewProjectDialogHandler_Type();
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.properties b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.properties
new file mode 100644
index 0000000..c1ba692
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.properties
@@ -0,0 +1,14 @@
+NewFolderDialogHandler_ParentFolder=Parent Folder
+NewFolderDialogHandler_FolderName=Folder name
+NewFolderDialogHandler_ShellTitle=New Folder
+NewFolderDialogHandler_Title=Folder
+NewFolderDialogHandler_Message=Create a new folder resource.
+NewFolderDialogHandler_ErrorSelectAParentFolder=Select a parent folder
+NewFolderDialogHandler_ErrorEnterFolderName=Enter a folder name
+
+NewProjectDialogHandler_ShellTitle=New Project
+NewProjectDialogHandler_Title=Project
+NewProjectDialogHandler_Message=Create a new project resource.
+NewProjectDialogHandler_Name=Name
+NewProjectDialogHandler_Type=Type
+NewFolderDialogHandler_ErrorFolderCreation=Failed to create folder
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewFolderDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewFolderDialogHandler.java
new file mode 100644
index 0000000..a14a261
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewFolderDialogHandler.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import javax.inject.Named;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.e4.demo.simpleide.ui.ResourceViewerControl;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class NewFolderDialogHandler {
+
+	@Execute
+	public void openNewTextFileDialog(
+			@Named(IServiceConstants.ACTIVE_SHELL) Shell parentShell,
+			@Optional @Named(IServiceConstants.SELECTION) final IResource resource,
+			final IWorkspace workspace, IProgressMonitor monitor,
+			final Logger logger, final INLSLookupFactoryService nlsFactory) {
+
+		TitleAreaDialog dialog = new TitleAreaDialog(parentShell) {
+			private ResourceViewerControl viewer;
+			private Text text;
+			private Messages messages = nlsFactory
+					.createNLSLookup(Messages.class);
+
+			@Override
+			protected Control createDialogArea(Composite parent) {
+
+				getShell()
+						.setText(messages.NewFolderDialogHandler_ShellTitle());
+				setTitle(messages.NewFolderDialogHandler_Title());
+				setMessage(messages.NewFolderDialogHandler_Message());
+
+				Composite comp = (Composite) super.createDialogArea(parent);
+				Composite container = new Composite(comp, SWT.NONE);
+				container.setLayoutData(new GridData(GridData.FILL_BOTH));
+				container.setLayout(new GridLayout(2, false));
+
+				Label label = new Label(container, SWT.NONE);
+				label.setLayoutData(new GridData(
+						GridData.VERTICAL_ALIGN_BEGINNING));
+				label.setText(messages.NewFolderDialogHandler_ParentFolder());
+
+				viewer = new ResourceViewerControl(container, SWT.NONE,
+						workspace, resource);
+				viewer.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+				label = new Label(container, SWT.NONE);
+				label.setText(messages.NewFolderDialogHandler_FolderName());
+
+				text = new Text(container, SWT.BORDER);
+				text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+				return comp;
+			}
+
+			@Override
+			protected void okPressed() {
+				IResource resource = viewer.getResource();
+				if (resource == null) {
+					setMessage(
+							messages.NewFolderDialogHandler_ErrorSelectAParentFolder(),
+							IMessageProvider.ERROR);
+					return;
+				}
+
+				if (text.getText().trim().length() == 0) {
+					setMessage(
+							messages.NewFolderDialogHandler_ErrorEnterFolderName(),
+							IMessageProvider.ERROR);
+					return;
+				}
+
+				IPath newFolderPath = resource.getFullPath().append(
+						text.getText());
+				IFolder folder = workspace.getRoot().getFolder(newFolderPath);
+				try {
+					folder.create(false, true, null);
+					super.okPressed();
+				} catch (CoreException e) {
+					logger.error(e);
+					setMessage(messages.NewFolderDialogHandler_ErrorFolderCreation(), IMessageProvider.ERROR);
+				}
+			}
+		};
+
+		dialog.open();
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewProjectDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewProjectDialogHandler.java
new file mode 100644
index 0000000..213f820
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewProjectDialogHandler.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import javax.inject.Named;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.internal.ServiceRegistryComponent;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class NewProjectDialogHandler {
+	private Map<IProjectService, Image> images = new HashMap<IProjectService, Image>();
+	private String projectName = ""; //$NON-NLS-1$
+	private IProjectService creator;
+
+	@Execute
+	public void openNewProjectDialog(
+			@Named(IServiceConstants.ACTIVE_SHELL) Shell parentShell,
+			IWorkspace workspace, IProgressMonitor monitor,
+			final ServiceRegistryComponent serviceRegistry,
+			StatusReporter reporter, Logger logger,
+			final INLSLookupFactoryService nlsFactory) {
+		
+		TitleAreaDialog dialog = new TitleAreaDialog(parentShell) {
+			private Text projectName;
+			private TableViewer projectType;
+			private Messages messages = nlsFactory
+					.createNLSLookup(Messages.class);
+
+			@Override
+			protected int getShellStyle() {
+				return super.getShellStyle() | SWT.SHEET;
+			}
+
+			@Override
+			protected Control createDialogArea(Composite parent) {
+				Composite comp = (Composite) super.createDialogArea(parent);
+				getShell().setText(messages.NewProjectDialogHandler_ShellTitle());
+				setTitle(messages.NewProjectDialogHandler_Title());
+				setMessage(messages.NewProjectDialogHandler_Message());
+
+				final Image titleImage = new Image(parent.getDisplay(),
+						getClass().getClassLoader().getResourceAsStream(
+								"/icons/wizard/newprj_wiz.png"));
+
+				setTitleImage(titleImage);
+
+				final Image shellImg = new Image(parent.getDisplay(),
+						getClass().getClassLoader().getResourceAsStream(
+								"/icons/newprj_wiz.gif"));
+				getShell().setImage(shellImg);
+				getShell().addDisposeListener(new DisposeListener() {
+
+					public void widgetDisposed(DisposeEvent e) {
+						shellImg.dispose();
+						titleImage.dispose();
+					}
+				});
+
+				Composite container = new Composite(comp, SWT.NONE);
+				container.setLayoutData(new GridData(GridData.FILL_BOTH));
+				container.setLayout(new GridLayout(2, false));
+
+				Label l = new Label(container, SWT.NONE);
+				l.setText(messages.NewProjectDialogHandler_Name());
+
+				projectName = new Text(container, SWT.BORDER);
+				projectName
+						.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+				l = new Label(container, SWT.NONE);
+				l.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+				l.setText(messages.NewProjectDialogHandler_Type());
+
+				projectType = new TableViewer(container);
+				projectType.setContentProvider(new ArrayContentProvider());
+				projectType.setLabelProvider(new LabelProvider() {
+					@Override
+					public String getText(Object element) {
+						IProjectService el = (IProjectService) element;
+						return el.getLabel();
+					}
+
+					@Override
+					public Image getImage(Object element) {
+						IProjectService el = (IProjectService) element;
+						Image img = images.get(el);
+						if (img == null) {
+							URL url;
+							InputStream in = null;
+							try {
+								url = FileLocator.find(new URL(el.getIconURI()));
+								in = url.openStream();
+								img = new Image(getShell().getDisplay(), in);
+								images.put(el, img);
+							} catch (MalformedURLException e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
+							} catch (IOException e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
+							} finally {
+								if (in != null) {
+									try {
+										in.close();
+									} catch (IOException e) {
+									}
+								}
+							}
+						}
+						return img;
+					}
+				});
+
+				Vector<IProjectService> creators = serviceRegistry
+						.getCreators();
+				projectType.setInput(creators);
+				if (creators.size() > 0) {
+					projectType.setSelection(new StructuredSelection(creators
+							.get(0)));
+				}
+				projectType.getControl().setLayoutData(
+						new GridData(GridData.FILL_BOTH));
+
+				getShell().addDisposeListener(new DisposeListener() {
+
+					public void widgetDisposed(DisposeEvent e) {
+						for (Image img : images.values()) {
+							img.dispose();
+						}
+						images.clear();
+					}
+				});
+
+				return comp;
+			}
+
+			@Override
+			protected void okPressed() {
+				if (projectType.getSelection().isEmpty()) {
+					setMessage("Please select a project type",
+							IMessageProvider.ERROR);
+					return;
+				}
+
+				if (projectName.getText().trim().length() == 0) {
+					setMessage("Please enter a projectname",
+							IMessageProvider.ERROR);
+					return;
+				}
+
+				NewProjectDialogHandler.this.creator = (IProjectService) ((IStructuredSelection) projectType
+						.getSelection()).getFirstElement();
+				NewProjectDialogHandler.this.projectName = projectName
+						.getText();
+
+				super.okPressed();
+			}
+		};
+
+		if (dialog.open() == IDialogConstants.OK_ID) {
+			creator.createProject(parentShell, workspace, reporter, logger,
+					monitor, projectName);
+		}
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewTextFileDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewTextFileDialogHandler.java
new file mode 100644
index 0000000..e456f24
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewTextFileDialogHandler.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import javax.inject.Named;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.demo.simpleide.ui.ResourceViewerControl;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class NewTextFileDialogHandler {
+	private IContainer parentContainer;
+	private String name;
+	
+	@Execute
+	public void openNewTextFileDialog(
+			@Named(IServiceConstants.ACTIVE_SHELL) Shell parentShell,
+			@Optional @Named(IServiceConstants.SELECTION) final IResource resource,
+			final IWorkspace workspace,
+			IProgressMonitor monitor) {
+		
+		TitleAreaDialog dialog = new TitleAreaDialog(parentShell) {
+			private ResourceViewerControl viewer;
+			private Text text;
+			
+			@Override
+			protected Control createDialogArea(Composite parent) {
+				Composite comp = (Composite) super.createDialogArea(parent);
+				Composite container = new Composite(comp,SWT.NONE);
+				container.setLayoutData(new GridData(GridData.FILL_BOTH));
+				container.setLayout(new GridLayout(2,false));
+				
+				Label label = new Label(container, SWT.NONE);
+				label.setText("Folder");
+				
+				viewer = new ResourceViewerControl(container, SWT.NONE, workspace, resource);
+				viewer.setLayoutData(new GridData(GridData.FILL_BOTH));
+				
+				label = new Label(container, SWT.NONE);
+				label.setText("File name");
+				
+				text = new Text(container, SWT.BORDER);
+				text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+				
+				return comp;
+			}
+			
+			@Override
+			protected void okPressed() {
+				IResource resource = viewer.getResource();
+				if( resource == null ) {
+					setMessage("Select a parent folder", IMessageProvider.ERROR);
+					return;
+				}
+				
+				if( text.getText().trim().length() == 0 ) {
+					setMessage("Enter a folder name", IMessageProvider.ERROR);
+					return;
+				}
+				
+				parentContainer = (IContainer) resource;
+				name = text.getText();
+				super.okPressed();
+			}
+		};
+		
+		if( dialog.open() == IDialogConstants.OK_ID ) {
+			IPath newFilePath = parentContainer.getFullPath().append(name);
+			IFile file = workspace.getRoot().getFile(newFilePath);
+			ByteArrayInputStream out = new ByteArrayInputStream(new byte[0]);
+			try {
+				file.create(out, true, monitor);
+			} catch (CoreException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			
+			try {
+				out.close(); 
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveAllHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveAllHandler.java
new file mode 100644
index 0000000..f272b42
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveAllHandler.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+
+public class SaveAllHandler {
+	@Execute
+	public void saveAll(EPartService partService) {
+		partService.saveAll(false);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveHandler.java
new file mode 100644
index 0000000..0a41173
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveHandler.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+
+public class SaveHandler {
+	@Execute
+	public void save(EPartService partService) {
+		MPart part = partService.getActivePart();
+		if( part != null && part.isDirty() ) {
+			partService.savePart(part, false);
+		}
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SwitchThemeHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SwitchThemeHandler.java
new file mode 100644
index 0000000..d11d606
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SwitchThemeHandler.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import javax.inject.Named;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
+
+public class SwitchThemeHandler {
+	private static final String THEME_BUNDLE = "org.eclipse.e4.ui.workbench.swt";
+	private static final String THEMEID_KEY = "themeid";
+
+	
+	@Execute
+	public void switchTheme(@Named("simpleide.command.switchtheme.themeid") String themeId, IThemeEngine engine) {		
+		engine.setTheme(themeId,true);
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/DefaultProjectService.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/DefaultProjectService.java
new file mode 100644
index 0000000..4da5c81
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/DefaultProjectService.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+public class DefaultProjectService implements IProjectService {
+
+	public void createProject(Shell shell, IWorkspace workspace, StatusReporter statusReporter, Logger looger,
+			IProgressMonitor monitor, String projectName) {
+		final IProject project = workspace.getRoot().getProject(projectName);
+		final IProjectDescription pd = workspace
+				.newProjectDescription(projectName);
+		try {
+			workspace.run(new IWorkspaceRunnable() { 
+
+				public void run(IProgressMonitor monitor) throws CoreException {
+					if (!project.exists()) {
+						project.create(pd, monitor);
+					}
+					if (!project.isOpen()) {
+						project.open(monitor);
+					}
+				}
+				
+			},monitor);
+		} catch (CoreException e) {
+			// TODO: handle exception
+		}
+	}
+
+	public String getIconURI() {
+		return "platform:/plugin/" + FrameworkUtil.getBundle(getClass()).getSymbolicName() + "/icons/newprj_wiz.gif";
+	}
+
+	public String getLabel() {
+		return "Project";
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/EclipseProjectImportService.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/EclipseProjectImportService.java
new file mode 100644
index 0000000..3aa2895
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/EclipseProjectImportService.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.ExternalProjectImportWizard;
+import org.eclipse.e4.demo.simpleide.services.IImportResourceService;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+public class EclipseProjectImportService implements IImportResourceService {
+
+	public String getIconURI() {
+		return "platform:/plugin/" + FrameworkUtil.getBundle(getClass()).getSymbolicName() + "/icons/newprj_wiz.gif";
+	}
+
+	public String getLabel() {
+		return "Existing Projects Into Workspace";
+	}
+
+	public void importResource(Shell shell, IEclipseContext context) {
+		ExternalProjectImportWizard wz = ContextInjectionFactory.make(ExternalProjectImportWizard.class, context);
+		WizardDialog dialog = new WizardDialog(shell, wz);
+		dialog.open();
+	}
+
+	public String getCategoryName() {
+		return "General";
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ImageServiceFunction.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ImageServiceFunction.java
new file mode 100644
index 0000000..5f76507
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ImageServiceFunction.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.services.ImageService;
+
+public class ImageServiceFunction extends ContextFunction {
+
+	@Override
+	public Object compute(IEclipseContext context) {
+		return ContextInjectionFactory.make(ImageService.class, context);
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/NLSLookupFactoryServiceImpl.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/NLSLookupFactoryServiceImpl.java
new file mode 100644
index 0000000..b57ae1e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/NLSLookupFactoryServiceImpl.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+
+public class NLSLookupFactoryServiceImpl implements INLSLookupFactoryService {
+	static class Entry {
+		private Class<?> clazz;
+		private Locale locale;
+
+		Entry(Class<?> clazz, Locale locale) {
+			this.clazz = clazz;
+			this.locale = locale;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
+			result = prime * result
+					+ ((locale == null) ? 0 : locale.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Entry other = (Entry) obj;
+			if (clazz == null) {
+				if (other.clazz != null)
+					return false;
+			} else if (!clazz.equals(other.clazz))
+				return false;
+			if (locale == null) {
+				if (other.locale != null)
+					return false;
+			} else if (!locale.equals(other.locale))
+				return false;
+			return true;
+		}
+	}
+
+	private Map<Entry, Object> CACHE = new ConcurrentHashMap<Entry, Object>();
+//	private Map<String,List<ITranslationService>> translationServices = new ConcurrentHashMap<String, List<ITranslationService>>();
+
+	public void addTranslationService(ITranslationService translationService, Map<String, Object> properties) {
+		System.err.println("Added Service: " + translationService);
+		System.err.println("Properties: " + properties);
+	}
+	
+	public void removeTranslationService(ITranslationService translationService, Map<String, Object> properties) {
+		System.err.println("Removed Service: " + translationService);
+		System.err.println("Properties: " + properties);
+	}
+	
+	public String translate(String category, String key, Object... args) {
+		return translate(category, key, Locale.getDefault(), args);
+	}
+	
+	public String translate(String category, String key, Locale locale, Object... args) {
+		throw new UnsupportedOperationException("OSGi Service based translation is not implemented yet!");
+	}
+	
+	public <L> L createDynamicNLSLookup(Class<L> clazz) {
+		return createNLSLookup(clazz, null);
+	}
+
+	public <L> L createNLSLookup(Class<L> clazz) {
+		return createNLSLookup(clazz, Locale.getDefault());
+	}
+
+	public <L> L createNLSLookup(Class<L> clazz, Locale locale) {
+		if (clazz.getAnnotation(Cache.class) != null) {
+			return createFromCache(clazz, locale);
+		}
+		return create(clazz, locale);
+	}
+
+	@SuppressWarnings("unchecked")
+	private <L> L createFromCache(Class<L> clazz, Locale locale) {
+		Entry entry = new Entry(clazz, locale);
+		Object rv = CACHE.get(entry);
+		if (rv != null) {
+			L l = create(clazz, locale);
+			CACHE.put(entry, l);
+			return l;
+		} else {
+			return (L) rv;
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private <L> L create(Class<L> clazz, Locale locale) {
+		OSGiService osgiService = clazz.getAnnotation(OSGiService.class);
+		if (osgiService != null) {
+			throw new UnsupportedOperationException("OSGi Service based translation is not implemented yet!");
+		} else {
+			return (L) Proxy.newProxyInstance(clazz.getClassLoader(),
+					new Class<?>[] { clazz }, new NLSFileInvocationHandler(
+							clazz, locale));
+		}
+	}
+	
+//	private static class NLSServiceInvocationHandler implements InvocationHandler {
+//
+//		public Object invoke(Object proxy, Method method, Object[] args)
+//				throws Throwable {
+//			// TODO Auto-generated method stub
+//			return null;
+//		}
+//		
+//	}
+
+	private static class NLSFileInvocationHandler implements InvocationHandler {
+		private static final String EXTENSION = ".properties"; //$NON-NLS-1$
+
+		private Properties properties;
+
+		public NLSFileInvocationHandler(Class<?> clazz, Locale locale) {
+			properties = initProperties(clazz, locale);
+		}
+
+		private static Properties initProperties(Class<?> clazz, Locale locale) {
+			String plain = clazz.getName();
+			String language = plain + "_" + locale.getLanguage();
+			String country = language + "_" + locale.getCountry();
+			String variant = country + "_" + locale.getVariant();
+
+			ClassLoader loader = clazz.getClassLoader();
+			Properties properties = new Properties();
+
+			for (String aVariant : new String[] { plain, language, country,
+					variant }) {
+				String file = aVariant.replace('.', '/') + EXTENSION;
+				final InputStream input = loader == null ? ClassLoader
+						.getSystemResourceAsStream(file) : loader
+						.getResourceAsStream(file);
+				if (input == null) {
+					continue;
+				}
+
+				try {
+					properties.load(input);
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			return properties;
+		}
+
+		public Object invoke(Object proxy, Method method, Object[] args)
+				throws Throwable {
+			if (properties == null) {
+				return "Lookup is disposed";
+			} else {
+				Key tmp = method.getAnnotation(Key.class);
+				String key;
+				String value;
+				if (tmp == null) {
+					key = method.getName();
+				} else {
+					key = tmp.key();
+				}
+
+				value = properties.getProperty(key);
+				if (value != null) {
+					if (args != null && args.length > 0) {
+						return MessageFormat.format(value, args);
+					} else {
+						return value;
+					}
+				} else {
+					return "***NLS '" + key + "' UNKNOWN***";
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ServiceRegistryComponent.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ServiceRegistryComponent.java
new file mode 100644
index 0000000..99f6f2c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ServiceRegistryComponent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import java.util.Vector;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+
+public class ServiceRegistryComponent {
+	private Vector<IProjectService> creators = new Vector<IProjectService>();
+	
+	public void addProjectService( IProjectService creator ) {
+		creators.add(creator);
+	}
+	
+	public void removeProjectService(IProjectService creator) {
+		creators.remove(creator);
+	}
+	
+	public Vector<IProjectService> getCreators() {
+		return creators;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ThemeMenuProcessor.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ThemeMenuProcessor.java
new file mode 100644
index 0000000..a1dd970
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ThemeMenuProcessor.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+
+import javax.inject.Inject;
+
+import java.util.List;
+import org.eclipse.e4.ui.css.swt.theme.ITheme;
+import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
+import org.eclipse.e4.ui.css.swt.theme.IThemeManager;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MCommandsFactory;
+import org.eclipse.e4.ui.model.application.commands.MParameter;
+import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.widgets.Display;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+public class ThemeMenuProcessor {
+
+	@Inject
+	@Named("simpleide.mainmenu")
+	private MMenu menu;
+	
+	@Execute
+	public void process() {
+		if( menu == null ) {
+			return;
+		}
+		
+		MTrimmedWindow window = (MTrimmedWindow) ((EObject) menu).eContainer();
+		
+		//FIXME Remove once bug 314091 is resolved
+		Bundle bundle = FrameworkUtil.getBundle(getClass());
+		BundleContext context = bundle.getBundleContext();
+		
+		ServiceReference reference = context.getServiceReference(IThemeManager.class.getName());
+		IThemeManager mgr = (IThemeManager) context.getService(reference);
+		IThemeEngine engine = mgr.getEngineForDisplay(Display.getCurrent());
+		
+		List<ITheme> themes = engine.getThemes();
+		if (themes.size() > 0) {
+			MApplication application = (MApplication) ((EObject) window)
+					.eContainer();
+			MCommand switchThemeCommand = null;
+			for (MCommand cmd : application.getCommands()) {
+				if ("simpleide.command.switchtheme".equals(cmd.getElementId())) { //$NON-NLS-1$
+					switchThemeCommand = cmd;
+					break;
+				}
+			}
+
+			if (switchThemeCommand != null) {
+				MMenu themesMenu = MMenuFactory.INSTANCE.createMenu();
+				themesMenu.setLabel("Themes"); //$NON-NLS-1$
+
+				for (ITheme theme : themes) {
+					MHandledMenuItem item = MMenuFactory.INSTANCE
+							.createHandledMenuItem();
+					item.setLabel(theme.getLabel());
+					item.setCommand(switchThemeCommand);
+					MParameter parameter = MCommandsFactory.INSTANCE
+							.createParameter();
+					parameter.setName("simpleide.command.switchtheme.themeid"); //$NON-NLS-1$
+					parameter.setValue(theme.getId());
+					item.getParameters().add(parameter);
+					themesMenu.getChildren().add(item);
+				}
+				
+				menu.getChildren().add(themesMenu);
+			}
+		}
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ArchiveFileManipulations.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ArchiveFileManipulations.java
new file mode 100644
index 0000000..9de8346
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ArchiveFileManipulations.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *     Red Hat, Inc - Extracted methods from WizardArchiveFileResourceImportPage1
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.IOException;
+import java.util.zip.ZipFile;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @since 3.1
+ */
+public class ArchiveFileManipulations {
+	
+	/**
+	 * Determine whether the file with the given filename is in .tar.gz or .tar
+	 * format.
+	 * 
+	 * @param fileName
+	 *            file to test
+	 * @return true if the file is in tar format
+	 */
+	public static boolean isTarFile(String fileName, Messages messages) {
+		if (fileName.length() == 0) {
+			return false;
+		}
+
+		TarFile tarFile = null;
+		try {
+			tarFile = new TarFile(fileName,messages);
+		} catch (TarException tarException) {
+			return false;
+		} catch (IOException ioException) {
+			return false;
+		} finally {
+			if (tarFile != null) {
+				try {
+					tarFile.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Determine whether the file with the given filename is in .zip or .jar
+	 * format.
+	 * 
+	 * @param fileName
+	 *            file to test
+	 * @return true if the file is in tar format
+	 */
+	public static boolean isZipFile(String fileName) {
+		if (fileName.length() == 0) {
+			return false;
+		}
+
+		ZipFile zipFile = null;
+		try {
+			zipFile = new ZipFile(fileName);
+		} catch (IOException ioException) {
+			return false;
+		} finally {
+			if (zipFile != null) {
+				try {
+					zipFile.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Closes the given structure provider.
+	 * 
+	 * @param structureProvider
+	 *            The structure provider to be closed, can be <code>null</code>				 
+	 * @param shell
+	 *            The shell to display any possible Dialogs in
+	 */
+	public static void closeStructureProvider(Messages messages, ILeveledImportStructureProvider structureProvider, Shell shell) {
+		if (structureProvider instanceof ZipLeveledStructureProvider) {
+			closeZipFile(messages, ((ZipLeveledStructureProvider) structureProvider).getZipFile(), shell);
+		}
+		if (structureProvider instanceof TarLeveledStructureProvider) {
+			closeTarFile(messages, ((TarLeveledStructureProvider) structureProvider).getTarFile(), shell);
+		}
+	}
+
+	/**
+	 * Attempts to close the passed zip file, and answers a boolean indicating
+	 * success.
+	 * 
+	 * @param file
+	 *            The zip file to attempt to close
+	 * @param shell
+	 *            The shell to display error dialogs in
+	 * @return Returns true if the operation was successful
+	 */
+	public static boolean closeZipFile(Messages messages, ZipFile file, Shell shell) {
+		try {
+			file.close();
+		} catch (IOException e) {
+			displayErrorDialog(
+					NLS.bind(messages.ZipImport_couldNotClose(), file.getName()),
+					shell);
+			return false;
+		}
+
+		return true;
+	}
+	
+	/**
+	 * Attempts to close the passed tar file, and answers a boolean indicating
+	 * success.
+	 * 
+	 * @param file
+	 *            The tar file to attempt to close
+	 * @param shell
+	 *            The shell to display error dialogs in
+	 * @return Returns true if the operation was successful
+	 * @since 3.4
+	 */
+	public static boolean closeTarFile(Messages messages, TarFile file, Shell shell) {
+		try {
+			file.close();
+		} catch (IOException e) {
+			displayErrorDialog(
+					NLS.bind(messages.ZipImport_couldNotClose(), file.getName()),
+					shell);
+			return false;
+		}
+		
+		return true;
+	}
+
+	/**
+	 * Display an error dialog with the specified message.
+	 * 
+	 * @param message
+	 *            the error message
+	 */
+	protected static void displayErrorDialog(String message, Shell shell) {
+		MessageDialog.open(MessageDialog.ERROR, shell, getErrorDialogTitle(), message, SWT.SHEET);
+	}
+
+	/**
+	 * Get the title for an error dialog. Subclasses should override.
+	 */
+	protected static String getErrorDialogTitle() {
+		return IDEWorkbenchMessages.WizardExportPage_internalErrorTitle;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ExternalProjectImportWizard.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ExternalProjectImportWizard.java
new file mode 100644
index 0000000..fe8fd54
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ExternalProjectImportWizard.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import javax.inject.Inject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+
+/**
+ * Standard workbench wizard for importing projects defined outside of the
+ * currently defined projects into Eclipse.
+ * <p>
+ * This class may be instantiated and used without further configuration; this
+ * class is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example:
+ * 
+ * <pre>
+ * IWizard wizard = new ExternalProjectImportWizard();
+ * wizard.init(workbench, selection);
+ * WizardDialog dialog = new WizardDialog(shell, wizard);
+ * dialog.open();
+ * </pre>
+ * 
+ * During the call to <code>open</code>, the wizard dialog is presented to the
+ * user. When the user hits Finish, a project is created with the location
+ * specified by the user.
+ * </p>
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class ExternalProjectImportWizard extends Wizard {
+	//    private static final String EXTERNAL_PROJECT_SECTION = "ExternalProjectImportWizard";//$NON-NLS-1$
+	private WizardProjectsImportPage mainPage;
+	private IStructuredSelection currentSelection = null;
+	private String initialPath = null;
+
+	private IWorkspace workspace;
+	private StatusReporter statusReporter;
+	private Logger logger;
+	private Messages messsagesLookup;
+
+	/**
+	 * Constructor for ExternalProjectImportWizard.
+	 */
+	@Inject
+	public ExternalProjectImportWizard(IWorkspace workspace,
+			StatusReporter statusReporter, Logger logger,
+			INLSLookupFactoryService lookupService) {
+		this(workspace, statusReporter, logger, null, lookupService);
+	}
+
+	/**
+	 * Constructor for ExternalProjectImportWizard.
+	 * 
+	 * @param initialPath
+	 *            Default path for wizard to import
+	 * @since 3.5
+	 */
+	public ExternalProjectImportWizard(IWorkspace workspace,
+			StatusReporter statusReporter, Logger logger, String initialPath,
+			INLSLookupFactoryService lookupService) {
+		super();
+		this.messsagesLookup = lookupService.createNLSLookup(Messages.class);
+		this.workspace = workspace;
+		this.statusReporter = statusReporter;
+		this.logger = logger;
+		this.initialPath = initialPath;
+		setNeedsProgressMonitor(true);
+		// IDialogSettings workbenchSettings =
+		// IDEWorkbenchPlugin.getDefault().getDialogSettings();
+		//
+		// IDialogSettings wizardSettings = workbenchSettings
+		// .getSection(EXTERNAL_PROJECT_SECTION);
+		// if (wizardSettings == null) {
+		// wizardSettings = workbenchSettings
+		// .addNewSection(EXTERNAL_PROJECT_SECTION);
+		// }
+		// setDialogSettings(wizardSettings);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWizard.
+	 */
+	public void addPages() {
+		super.addPages();
+		mainPage = new WizardProjectsImportPage(
+				"wizardExternalProjectsPage", initialPath, currentSelection, workspace, statusReporter, logger, messsagesLookup); //$NON-NLS-1$
+		addPage(mainPage);
+	}
+
+	// TODO SimpleIDE
+	// /* (non-Javadoc)
+	// * Method declared on IWorkbenchWizard.
+	// */
+	// public void init(IWorkbench workbench, IStructuredSelection
+	// currentSelection) {
+	// setWindowTitle(DataTransferMessages.DataTransfer_importTitle);
+	// setDefaultPageImageDescriptor(
+	//				IDEWorkbenchPlugin.getIDEImageDescriptor("wizban/importproj_wiz.png")); //$NON-NLS-1$
+	// this.currentSelection = currentSelection;
+	// }
+
+	/*
+	 * (non-Javadoc) Method declared on IWizard.
+	 */
+	public boolean performCancel() {
+		mainPage.performCancel();
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IWizard.
+	 */
+	public boolean performFinish() {
+		return mainPage.createProjects();
+	}
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/FileSystemStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/FileSystemStructureProvider.java
new file mode 100644
index 0000000..1d263fe
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/FileSystemStructureProvider.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.e4.core.services.log.Logger;
+
+//import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * This class provides information regarding the structure and
+ * content of specified file system File objects.
+ */
+public class FileSystemStructureProvider implements IImportStructureProvider {
+
+    /**
+     * Holds a singleton instance of this class.
+     */
+//    public final static FileSystemStructureProvider INSTANCE = new FileSystemStructureProvider();
+    
+    private Logger logger;
+
+    /**
+     * Creates an instance of <code>FileSystemStructureProvider</code>.
+     */
+    FileSystemStructureProvider(Logger logger) {
+        super();
+        this.logger = logger;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IImportStructureProvider
+     */
+    public List<File> getChildren(Object element) {
+        File folder = (File) element;
+        String[] children = folder.list();
+        int childrenLength = children == null ? 0 : children.length;
+        List<File> result = new ArrayList<File>(childrenLength);
+
+        for (int i = 0; i < childrenLength; i++) {
+			result.add(new File(folder, children[i]));
+		}
+
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IImportStructureProvider
+     */
+    public InputStream getContents(Object element) {
+        try {
+            return new FileInputStream((File) element);
+        } catch (FileNotFoundException e) {
+        	logger.error(e);
+//        	IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+            return null;
+        }
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IImportStructureProvider
+     */
+    public String getFullPath(Object element) {
+        return ((File) element).getPath();
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IImportStructureProvider
+     */
+    public String getLabel(Object element) {
+
+        //Get the name - if it is empty then return the path as it is a file root
+        File file = (File) element;
+        String name = file.getName();
+        if (name.length() == 0) {
+			return file.getPath();
+		}
+        return name;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IImportStructureProvider
+     */
+    public boolean isFolder(Object element) {
+        return ((File) element).isDirectory();
+    }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IDEWorkbenchMessages.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IDEWorkbenchMessages.java
new file mode 100644
index 0000000..f30309d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IDEWorkbenchMessages.java
@@ -0,0 +1,16 @@
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import org.eclipse.osgi.util.NLS;
+
+public class IDEWorkbenchMessages {
+	static {
+		NLS.initializeMessages(IDEWorkbenchMessages.class.getName(), IDEWorkbenchMessages.class);
+	}
+	public static String WizardDataTransfer_existsQuestion;
+	public static String WizardDataTransfer_overwriteNameAndPathQuestion;
+	public static String Question;
+	public static String WizardExportPage_internalErrorTitle;
+	public static String ContainerGenerator_pathOccupied;
+	public static String ContainerGenerator_progressMessage;
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IImportStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IImportStructureProvider.java
new file mode 100644
index 0000000..25d87da
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IImportStructureProvider.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Interface which can provide structure and content information 
+ * for an element (for example, a file system element).
+ * Used by the import wizards to abstract the commonalities
+ * between importing from the file system and importing from an archive.
+ */
+public interface IImportStructureProvider {
+    /**
+     * Returns a collection with the children of the specified structured element.
+     * 
+     * @param element the element for which to compute the children
+     * @return the list of child elements 
+     */
+	public List<?> getChildren(Object element);
+
+    /**
+     * Returns the contents of the specified structured element, or
+     * <code>null</code> if there is a problem determining the element's
+     * contents.
+     * <p>
+     * <strong>Note:</strong>: The client is responsible for closing the stream when finished.</p>
+     *
+     * @param element a structured element
+     * @return the contents of the structured element, or <code>null</code>
+     */
+    InputStream getContents(Object element);
+
+    /**
+     * Returns the full path of the specified structured element.
+     *
+     * @param element a structured element
+     * @return the display label of the structured element
+     */
+    String getFullPath(Object element);
+
+    /**
+     * Returns the display label of the specified structured element.
+     *
+     * @param element a structured element
+     * @return the display label of the structured element
+     */
+    String getLabel(Object element);
+
+    /**
+     * Returns a boolean indicating whether the passed structured element represents
+     * a container element (as opposed to a leaf element).
+     *
+     * @return boolean
+     * @param element java.lang.Object
+     */
+    boolean isFolder(Object element);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ILeveledImportStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ILeveledImportStructureProvider.java
new file mode 100644
index 0000000..f374098
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ILeveledImportStructureProvider.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Red Hat, Inc - setStrip(int), getStrip()
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+
+/**
+ * Interface which can provide structure and content information for an archive 
+ * element. Used by the import wizards to abstract the commonalities between 
+ * importing from the a zip file and importing from a tar file.
+ * 
+ * @since 3.1
+ */
+public interface ILeveledImportStructureProvider extends IImportStructureProvider {
+	/**
+	 * Returns the entry that this importer uses as the root sentinel.
+	 * 
+	 * @return root entry of the archive file
+	 */
+	public abstract Object getRoot();
+
+	/**
+	 * Tells the provider to strip N number of directories from the path of any
+	 * path or file name returned by the IImportStructureProvider (Default=0).
+	 * 
+	 * @param level
+	 *            The number of directories to strip
+	 */
+	public abstract void setStrip(int level);
+
+	/**
+	 * Returns the number of directories that this IImportStructureProvider is
+	 * stripping from the file name
+	 * 
+	 * @return int Number of entries
+	 */
+	public abstract int getStrip();
+	
+	/**
+	 * Close the archive file that was used to create this leveled structure provider.
+	 * 
+	 * @return <code>true</code> if the archive was closed successfully
+	 */
+	public boolean closeArchive();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ImportOperation.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ImportOperation.java
new file mode 100644
index 0000000..0f5a772
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ImportOperation.java
@@ -0,0 +1,986 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Red Hat, Inc - changed TarFileStructureProvider to TarLeveledStructureProvider 
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IPathVariableManager;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.actions.WorkspaceModifyOperation;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs.ContainerGenerator;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs.IOverwriteQuery;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * An operation which does the actual work of copying objects from the local file
+ * system into the workspace.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ImportOperation extends WorkspaceModifyOperation {
+    private static final int POLICY_DEFAULT = 0;
+
+    private static final int POLICY_SKIP_CHILDREN = 1;
+
+    private static final int POLICY_FORCE_OVERWRITE = 2;
+
+    private Object source;
+
+    private IPath destinationPath;
+
+    private IContainer destinationContainer;
+
+    private List<?> selectedFiles;
+
+    private List<?> rejectedFiles;
+
+    private IImportStructureProvider provider;
+
+    private IProgressMonitor monitor;
+
+    protected IOverwriteQuery overwriteCallback;
+
+    private Shell context;
+
+    private List<IStatus> errorTable = new ArrayList<IStatus>();
+
+    private boolean createVirtualFolder = false;
+
+    private boolean createLinks = false;
+    
+    private boolean createLinkFilesOnly = false;
+
+    private String relativeVariable = null;
+
+    private boolean createContainerStructure = true;
+
+    //The constants for the overwrite 3 state
+    private static final int OVERWRITE_NOT_SET = 0;
+
+    private static final int OVERWRITE_NONE = 1;
+
+    private static final int OVERWRITE_ALL = 2;
+
+    private int overwriteState = OVERWRITE_NOT_SET;
+
+	private static final String ABSOLUTE_PATH = "<Absolute Path>"; //$NON-NLS-1$
+	
+	private IWorkspace workspace;
+	
+	private Messages messages;
+
+	/**
+     * Creates a new operation that recursively imports the entire contents of the
+     * specified root file system object.
+     * <p>
+     * The <code>source</code> parameter represents the root file system object to 
+     * import. All contents of this object are imported. Valid types for this parameter
+     * are determined by the supplied <code>IImportStructureProvider</code>.
+     * </p>
+     * <p>
+     * The <code>provider</code> parameter allows this operation to deal with the
+     * source object in an abstract way. This operation calls methods on the provider
+     * and the provider in turn calls specific methods on the source object.
+     * </p>
+     *  <p>
+     * The default import behavior is to recreate the complete container structure
+     * for the contents of the root file system object in their destination. 
+     * If <code>setCreateContainerStructure</code> is set to false then the container 
+     * structure created is relative to the root file system object.
+     * </p>
+     * 
+     * @param containerPath the full path of the destination container within the
+     *   workspace
+     * @param source the root file system object to import
+     * @param provider the file system structure provider to use
+     * @param overwriteImplementor the overwrite strategy to use
+     */
+    public ImportOperation(IWorkspace workspace, IPath containerPath, Object source,
+            IImportStructureProvider provider,
+            IOverwriteQuery overwriteImplementor, Messages messages) {
+        super(workspace);
+        this.messages = messages;
+        this.workspace = workspace;
+        this.destinationPath = containerPath;
+        this.source = source;
+        this.provider = provider;
+        overwriteCallback = overwriteImplementor;
+    }
+
+    /**
+     * Creates a new operation that imports specific file system objects.
+     * In this usage context, the specified source file system object is used by the
+     * operation solely to determine the destination container structure of the file system
+     * objects being imported.
+     * <p>
+     * The <code>source</code> parameter represents the root file system object to 
+     * import. Valid types for this parameter are determined by the supplied 
+     * <code>IImportStructureProvider</code>. The contents of the source which
+     * are to be imported are specified in the <code>filesToImport</code>
+     * parameter.
+     * </p>
+     * <p>
+     * The <code>provider</code> parameter allows this operation to deal with the
+     * source object in an abstract way. This operation calls methods on the provider
+     * and the provider in turn calls specific methods on the source object.
+     * </p>
+     * <p>
+     * The <code>filesToImport</code> parameter specifies what contents of the root
+     * file system object are to be imported.
+     * </p>
+     * <p>
+     * The default import behavior is to recreate the complete container structure
+     * for the file system objects in their destination. If <code>setCreateContainerStructure</code>
+     * is set to <code>false</code>, then the container structure created for each of 
+     * the file system objects is relative to the supplied root file system object.
+     * </p>
+     *
+     * @param containerPath the full path of the destination container within the
+     *   workspace
+     * @param source the root file system object to import from
+     * @param provider the file system structure provider to use
+     * @param overwriteImplementor the overwrite strategy to use
+     * @param filesToImport the list of file system objects to be imported
+     *  (element type: <code>Object</code>)
+     */
+    public ImportOperation(IWorkspace workspace, IPath containerPath, Object source,
+            IImportStructureProvider provider,
+            IOverwriteQuery overwriteImplementor, List<?> filesToImport, Messages messages) {
+        this(workspace, containerPath, source, provider, overwriteImplementor, messages);
+        setFilesToImport(filesToImport);
+    }
+
+    /**
+     * Creates a new operation that imports specific file system objects.
+     * <p>
+     * The <code>provider</code> parameter allows this operation to deal with the
+     * source object in an abstract way. This operation calls methods on the provider
+     * and the provider in turn calls specific methods on the source object.
+     * </p>
+     * <p>
+     * The <code>filesToImport</code> parameter specifies what file system objects 
+     * are to be imported.
+     * </p>
+     * <p>
+     * The default import behavior is to recreate the complete container structure
+     * for the file system objects in their destination. If <code>setCreateContainerStructure</code>
+     * is set to <code>false</code>, then no container structure is created for each of 
+     * the file system objects.
+     * </p>
+     *
+     * @param containerPath the full path of the destination container within the
+     *   workspace
+     * @param provider the file system structure provider to use
+     * @param overwriteImplementor the overwrite strategy to use
+     * @param filesToImport the list of file system objects to be imported
+     *  (element type: <code>Object</code>)
+     */
+    public ImportOperation(IWorkspace workspace, IPath containerPath,
+            IImportStructureProvider provider,
+            IOverwriteQuery overwriteImplementor, List<?> filesToImport, Messages messages) {
+        this(workspace, containerPath, null, provider, overwriteImplementor,messages);
+        setFilesToImport(filesToImport);
+    }
+
+    /**
+     * Prompts if existing resources should be overwritten. Recursively collects
+     * existing read-only files to overwrite and resources that should not be
+     * overwritten.
+     * 
+     * @param sourceStart destination path to check for existing files
+     * @param sources file system objects that may exist in the destination
+     * @param noOverwrite files that were selected to be skipped (don't overwrite).
+     * 	object type IPath
+     * @param overwriteReadonly the collected existing read-only files to overwrite.
+     * 	object type IPath
+     * @param policy on of the POLICY constants defined in the
+     * class.
+     */
+    void collectExistingReadonlyFiles(IPath sourceStart, List<?> sources,
+            ArrayList<Object> noOverwrite, ArrayList<Object> overwriteReadonly, int policy) {
+        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+        Iterator<?> sourceIter = sources.iterator();
+        IPath sourceRootPath = null;
+
+        if (this.source != null) {
+            sourceRootPath = new Path(provider.getFullPath(this.source));
+        }
+        while (sourceIter.hasNext()) {
+            Object nextSource = sourceIter.next();
+            IPath sourcePath = new Path(provider.getFullPath(nextSource));
+            IPath newDestinationPath;
+            IResource newDestination;
+
+            if (sourceRootPath == null) {
+                newDestinationPath = sourceStart.append(provider
+                        .getLabel(nextSource));
+            } else {
+                int prefixLength = sourcePath
+                        .matchingFirstSegments(sourceRootPath);
+                IPath relativeSourcePath = sourcePath
+                        .removeFirstSegments(prefixLength);
+                newDestinationPath = this.destinationPath
+                        .append(relativeSourcePath);
+            }
+            newDestination = workspaceRoot.findMember(newDestinationPath);
+            if (newDestination == null) {
+				continue;
+			}
+
+            IFolder folder = getFolder(newDestination);
+            if (folder != null) {
+                if (policy != POLICY_FORCE_OVERWRITE) {
+                    if (this.overwriteState == OVERWRITE_NONE
+                            || !queryOverwrite(newDestinationPath)) {
+                        noOverwrite.add(folder);
+                        continue;
+                    }
+                }
+                if (provider.isFolder(nextSource)) {
+					collectExistingReadonlyFiles(newDestinationPath, provider
+                            .getChildren(nextSource), noOverwrite,
+                            overwriteReadonly, POLICY_FORCE_OVERWRITE);
+				}
+            } else {
+                IFile file = getFile(newDestination);
+
+                if (file != null) {
+                    if (!queryOverwriteFile(file, policy)) {
+						noOverwrite.add(file.getFullPath());
+					} else if (file.isReadOnly()) {
+						overwriteReadonly.add(file);
+					}
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates the folders that appear in the specified resource path.
+     * These folders are created relative to the destination container.
+     *
+     * @param path the relative path of the resource
+     * @return the container resource coresponding to the given path
+     * @exception CoreException if this method failed
+     */
+    IContainer createContainersFor(IPath path) throws CoreException {
+
+        IContainer currentFolder = destinationContainer;
+
+        int segmentCount = path.segmentCount();
+
+        //No containers to create
+        if (segmentCount == 0) {
+			return currentFolder;
+		}
+
+        //Needs to be handles differently at the root
+        if (currentFolder.getType() == IResource.ROOT) {
+			return createFromRoot(path);
+		}
+
+        for (int i = 0; i < segmentCount; i++) {
+            currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
+            if (!currentFolder.exists()) {
+                if (createVirtualFolder)
+					((IFolder) currentFolder).create(IResource.VIRTUAL, true,
+							null);
+                else if (createLinks)
+                    ((IFolder) currentFolder).createLink(createRelativePath(
+                            path, currentFolder), 0, null);
+                else
+                    ((IFolder) currentFolder).create(false, true, null);
+            }
+        }
+
+        return currentFolder;
+    }
+
+    /**
+     * Creates the folders that appear in the specified resource path
+     * assuming that the destinationContainer begins at the root. Do not create projects.
+     *
+     * @param path the relative path of the resource
+     * @return the container resource coresponding to the given path
+     * @exception CoreException if this method failed
+     */
+    private IContainer createFromRoot(IPath path) throws CoreException {
+
+        int segmentCount = path.segmentCount();
+
+        //Assume the project exists 
+        IContainer currentFolder = ((IWorkspaceRoot) destinationContainer)
+                .getProject(path.segment(0));
+
+        for (int i = 1; i < segmentCount; i++) {
+            currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
+            if (!currentFolder.exists()) {
+				((IFolder) currentFolder).create(false, true, null);
+			}
+        }
+
+        return currentFolder;
+    }
+
+    /**
+     * Deletes the given resource. If the resource fails to be deleted, adds a
+     * status object to the list to be returned by <code>getResult</code>.
+     *
+     * @param resource the resource
+     */
+    void deleteResource(IResource resource) {
+        try {
+            resource.delete(IResource.KEEP_HISTORY, null);
+        } catch (CoreException e) {
+            errorTable.add(e.getStatus());
+        }
+    }
+
+    /* (non-Javadoc)
+     * Method declared on WorkbenchModifyOperation.
+     * Imports the specified file system objects from the file system.
+     */
+    protected void execute(IProgressMonitor progressMonitor) {
+
+        monitor = progressMonitor;
+
+        try {
+            if (selectedFiles == null) {
+                //Set the amount to 1000 as we have no idea of how long this will take
+                monitor.beginTask(messages.ImportOperation_ImportTask(), 1000);
+                ContainerGenerator generator = new ContainerGenerator(workspace,
+                        destinationPath);
+                monitor.worked(30);
+                validateFiles(Arrays.asList(new Object[] { source }));
+                monitor.worked(50);
+                destinationContainer = generator
+                        .generateContainer(new SubProgressMonitor(monitor, 50));
+                importRecursivelyFrom(source, POLICY_DEFAULT);
+                //Be sure it finishes
+                monitor.worked(90);
+            } else {
+                // Choose twice the selected files size to take folders into account
+                int creationCount = selectedFiles.size();
+                monitor.beginTask(messages.ImportOperation_ImportTask(), creationCount + 100);
+                ContainerGenerator generator = new ContainerGenerator(workspace,
+                        destinationPath);
+                monitor.worked(30);
+                validateFiles(selectedFiles);
+                monitor.worked(50);
+                destinationContainer = generator
+                        .generateContainer(new SubProgressMonitor(monitor, 50));
+                importFileSystemObjects(selectedFiles);
+                monitor.done();
+            }
+        } catch (CoreException e) {
+            errorTable.add(e.getStatus());
+        } finally {
+            monitor.done();
+        }
+    }
+
+    /**
+     * Returns the container resource that the passed file system object should be
+     * imported into.
+     *
+     * @param fileSystemObject the file system object being imported
+     * @return the container resource that the passed file system object should be
+     *     imported into
+     * @exception CoreException if this method failed
+     */
+    IContainer getDestinationContainerFor(Object fileSystemObject)
+            throws CoreException {
+        IPath pathname = new Path(provider.getFullPath(fileSystemObject));
+
+        if (createContainerStructure) {
+			return createContainersFor(pathname.removeLastSegments(1));
+		}
+        if (source == fileSystemObject) {
+			return null;
+		}
+        IPath sourcePath = new Path(provider.getFullPath(source));
+        IPath destContainerPath = pathname.removeLastSegments(1);
+        IPath relativePath = destContainerPath.removeFirstSegments(
+                sourcePath.segmentCount()).setDevice(null);
+        return createContainersFor(relativePath);
+        
+    }
+
+    /**
+     * Returns the resource either casted to or adapted to an IFile. 
+     * 
+     * @param resource resource to cast/adapt
+     * @return the resource either casted to or adapted to an IFile.
+     * 	<code>null</code> if the resource does not adapt to IFile 
+     */
+    IFile getFile(IResource resource) {
+        if (resource instanceof IFile) {
+            return (IFile) resource;
+        }
+        Object adapted = ((IAdaptable) resource).getAdapter(IFile.class);
+        if(adapted == null) {
+			return null;
+		}
+        return (IFile) adapted;
+      
+    }
+
+    /**
+     * Returns the resource either casted to or adapted to an IFolder. 
+     * 
+     * @param resource resource to cast/adapt
+     * @return the resource either casted to or adapted to an IFolder.
+     * 	<code>null</code> if the resource does not adapt to IFolder 
+     */
+    IFolder getFolder(IResource resource) {
+        if (resource instanceof IFolder) {
+            return (IFolder) resource;
+        }
+        Object adapted = ((IAdaptable) resource).getAdapter(IFolder.class);
+        if(adapted == null) {
+			return null;
+		}
+        return (IFolder) adapted;
+    }
+
+    /**
+     * Returns the rejected files based on the given multi status.
+     *  
+     * @param multiStatus multi status to use to determine file rejection
+     * @param files source files
+     * @return list of rejected files as absolute paths. Object type IPath.
+     */
+    ArrayList<IPath> getRejectedFiles(IStatus multiStatus, IFile[] files) {
+        ArrayList<IPath> filteredFiles = new ArrayList<IPath>();
+
+        IStatus[] status = multiStatus.getChildren();
+        for (int i = 0; i < status.length; i++) {
+            if (status[i].isOK() == false) {
+            	errorTable.add(status[i]);
+            	filteredFiles.add(files[i].getFullPath());
+            }
+        }
+        return filteredFiles;
+    }
+
+    /**
+     * Returns the status of the import operation.
+     * If there were any errors, the result is a status object containing
+     * individual status objects for each error.
+     * If there were no errors, the result is a status object with error code <code>OK</code>.
+     *
+     * @return the status
+     */
+    public IStatus getStatus() {
+        IStatus[] errors = new IStatus[errorTable.size()];
+        errorTable.toArray(errors);
+        return new MultiStatus(getBundleName(), IStatus.OK, errors,
+                messages.ImportOperation_importProblems(),
+                null);
+    }
+
+    /**
+     * Imports the specified file system object into the workspace.
+     * If the import fails, adds a status object to the list to be returned by
+     * <code>getResult</code>.
+     *
+     * @param fileObject the file system object to be imported
+     * @param policy determines how the file object is imported
+     */
+    void importFile(Object fileObject, int policy) {
+        IContainer containerResource;
+        try {
+            containerResource = getDestinationContainerFor(fileObject);
+        } catch (CoreException e) {
+            IStatus coreStatus = e.getStatus();
+            String newMessage = NLS.bind(messages.ImportOperation_coreImportError(), fileObject, coreStatus.getMessage());
+            IStatus status = new Status(coreStatus.getSeverity(), coreStatus
+                    .getPlugin(), coreStatus.getCode(), newMessage, null);
+            errorTable.add(status);
+            return;
+        }
+
+        String fileObjectPath = provider.getFullPath(fileObject);
+        monitor.subTask(fileObjectPath);
+        IFile targetResource = containerResource.getFile(new Path(provider
+                .getLabel(fileObject)));
+        monitor.worked(1);
+
+        if (rejectedFiles.contains(targetResource.getFullPath())) {
+			return;
+		}
+
+        // ensure that the source and target are not the same
+        IPath targetPath = targetResource.getLocation();
+        // Use Files for comparison to avoid platform specific case issues
+        if (targetPath != null
+                && (targetPath.toFile().equals(new File(fileObjectPath)))) {
+            errorTable.add(new Status(IStatus.ERROR, getBundleName(), 0,
+                    NLS.bind(messages.ImportOperation_targetSameAsSourceError(), fileObjectPath), null));
+            return;
+        }
+
+        InputStream contentStream = provider.getContents(fileObject);
+        if (contentStream == null) {
+            errorTable
+                    .add(new Status(
+                            IStatus.ERROR,
+                            getBundleName(),
+                            0,
+                            NLS.bind(messages.ImportOperation_openStreamError(), fileObjectPath),
+                            null));
+            return;
+        }
+
+        try {
+            if (targetResource.exists()) {
+				targetResource.setContents(contentStream,
+                        IResource.KEEP_HISTORY, null);
+            } else {
+                if (createVirtualFolder || createLinks || createLinkFilesOnly)
+                    targetResource.createLink(createRelativePath(
+                            new Path(provider
+                                    .getFullPath(fileObject)), targetResource), 0, null);
+                else
+                    targetResource.create(contentStream, false, null);
+            }
+            setResourceAttributes(targetResource, fileObject);
+
+            if (provider instanceof TarLeveledStructureProvider) {
+            	try {
+            		targetResource.setResourceAttributes(((TarLeveledStructureProvider) provider).getResourceAttributes(fileObject));
+            	} catch (CoreException e) {
+            		errorTable.add(e.getStatus());
+            	}
+            }
+        } catch (CoreException e) {
+            errorTable.add(e.getStatus());
+        } finally {
+            try {
+                contentStream.close();
+            } catch (IOException e) {
+                errorTable
+                        .add(new Status(
+                                IStatus.ERROR,
+                                getBundleName(),
+                                0,
+                                NLS.bind(messages.ImportOperation_closeStreamError(), fileObjectPath),
+                                e));
+            }
+        }
+    }
+
+    private String getBundleName() {
+    	return FrameworkUtil.getBundle(getClass()).getSymbolicName();
+    }
+    
+    /**
+     * Reuse the file attributes set in the import.
+     * @param targetResource
+     * @param fileObject
+     */
+    private void setResourceAttributes(IFile targetResource, Object fileObject) {
+    	
+    	long timeStamp = 0;
+    	if(fileObject instanceof File) {
+			try {
+				targetResource.setResourceAttributes(ResourceAttributes.fromFile((File) fileObject));
+				timeStamp = ((File)fileObject).lastModified();
+			} catch (CoreException e) {
+        		errorTable.add(e.getStatus());
+			}
+		}else if (fileObject instanceof TarEntry) {
+        	try {
+        		targetResource.setResourceAttributes(((TarLeveledStructureProvider) provider).getResourceAttributes(fileObject));
+        		timeStamp = ((TarEntry)fileObject).getTime()*1000; // TarEntry time is in secs. Convert to msecs
+        	} catch (CoreException e) {
+        		errorTable.add(e.getStatus());
+        	}
+        }else if (fileObject instanceof ZipEntry) {
+			long zipTimeStamp = ((ZipEntry)fileObject).getTime();
+			if(zipTimeStamp != -1)
+				timeStamp = zipTimeStamp;
+        }
+		
+    	if(timeStamp!= 0) {
+    		try {
+				targetResource.setLocalTimeStamp(timeStamp);
+			} catch (CoreException e) {
+        		errorTable.add(e.getStatus());
+			}
+    	}
+	}
+
+	/**
+     * Imports the specified file system objects into the workspace.
+     * If the import fails, adds a status object to the list to be returned by
+     * <code>getStatus</code>.
+     *
+     * @param filesToImport the list of file system objects to import
+     *   (element type: <code>Object</code>)
+	 * @throws CoreException 
+     * @exception OperationCanceledException if canceled
+     */
+    void importFileSystemObjects(List<?> filesToImport) throws CoreException {
+        Iterator<?> filesEnum = filesToImport.iterator();
+        while (filesEnum.hasNext()) {
+            Object fileSystemObject = filesEnum.next();
+            if (source == null) {
+                // We just import what we are given into the destination
+                IPath sourcePath = new Path(provider
+                        .getFullPath(fileSystemObject)).removeLastSegments(1);
+                if (provider.isFolder(fileSystemObject) && sourcePath.isEmpty()) {
+                    // If we don't have a parent then we have selected the
+                    // file systems root. Roots can't copied (at least not
+                    // under windows).
+                    errorTable.add(new Status(IStatus.INFO,
+                    		getBundleName(), 0, messages.ImportOperation_cannotCopy(),
+                            null));
+                    continue;
+                }
+                source = sourcePath.toFile();
+            }
+            importRecursivelyFrom(fileSystemObject, POLICY_DEFAULT);
+        }
+    }
+
+    /**
+     * Imports the specified file system container object into the workspace.
+     * If the import fails, adds a status object to the list to be returned by
+     * <code>getResult</code>.
+     *
+     * @param folderObject the file system container object to be imported
+     * @param policy determines how the folder object and children are imported
+     * @return the policy to use to import the folder's children
+     * @throws CoreException 
+     */
+    int importFolder(Object folderObject, int policy) throws CoreException {
+        IContainer containerResource;
+        try {
+            containerResource = getDestinationContainerFor(folderObject);
+        } catch (CoreException e) {
+            errorTable.add(e.getStatus());
+            return policy;
+        }
+
+        if (containerResource == null) {
+			return policy;
+		}
+
+        monitor.subTask(provider.getFullPath(folderObject));
+        IWorkspace workspace = destinationContainer.getWorkspace();
+        IPath containerPath = containerResource.getFullPath();
+        IPath resourcePath = containerPath.append(provider
+                .getLabel(folderObject));
+
+        // Do not attempt the import if the resource path is unchanged. This may happen
+        // when importing from a zip file.
+        if (resourcePath.equals(containerPath)) {
+			return policy;
+		}
+
+        if (workspace.getRoot().exists(resourcePath)) {
+            if (rejectedFiles.contains(resourcePath)) {
+				return POLICY_SKIP_CHILDREN;
+			}
+
+            IFolder folder = workspace.getRoot().getFolder(resourcePath);
+            if (createVirtualFolder || createLinks || folder.isVirtual() || folder.isLinked()) {
+                folder.delete(true, null);
+            } else
+                return POLICY_FORCE_OVERWRITE;
+        }
+
+        try {
+            if (createVirtualFolder)
+				workspace.getRoot().getFolder(resourcePath).create(
+						IResource.VIRTUAL, true, null);
+            else if (createLinks) {
+            	IFolder newFolder = workspace.getRoot().getFolder(resourcePath);
+            	newFolder.createLink(
+                        createRelativePath(new Path(provider.getFullPath(folderObject)), newFolder),
+                        0, null);
+                policy = POLICY_SKIP_CHILDREN;
+            } else
+                workspace.getRoot().getFolder(resourcePath).create(false, true, null);
+        } catch (CoreException e) {
+            errorTable.add(e.getStatus());
+        }
+
+        return policy;
+    }
+
+    /**
+     * Transform an absolute path URI to a relative path one (i.e. from
+     * "C:\foo\bar\file.txt" to "VAR\file.txt" granted that the relativeVariable
+     * is "VAR" and points to "C:\foo\bar\").
+     * 
+     * @param location
+     * @param resource 
+     * @return an URI that was made relative to a variable
+     */
+    private IPath createRelativePath(IPath location, IResource resource) {
+		if (relativeVariable == null)
+			return location;
+		if (relativeVariable.equals(ABSOLUTE_PATH))
+			return location;
+		IPathVariableManager pathVariableManager = resource.getPathVariableManager();
+		try {
+			return URIUtil.toPath(pathVariableManager.convertToRelative(URIUtil.toURI(location), true, relativeVariable));
+		} catch (CoreException e) {
+			return location;
+		}
+	}
+
+	/**
+     * Imports the specified file system object recursively into the workspace.
+     * If the import fails, adds a status object to the list to be returned by
+     * <code>getStatus</code>.
+     *
+     * @param fileSystemObject the file system object to be imported
+     * @param policy determines how the file system object and children are imported
+	 * @throws CoreException 
+     * @exception OperationCanceledException if canceled
+     */
+    void importRecursivelyFrom(Object fileSystemObject, int policy) throws CoreException {
+        if (monitor.isCanceled()) {
+			throw new OperationCanceledException();
+		}
+
+        if (!provider.isFolder(fileSystemObject)) {
+            importFile(fileSystemObject, policy);
+            return;
+        }
+
+        int childPolicy = importFolder(fileSystemObject, policy);
+        if (childPolicy != POLICY_SKIP_CHILDREN) {
+            Iterator<?> children = provider.getChildren(fileSystemObject)
+                    .iterator();
+            while (children.hasNext()) {
+				importRecursivelyFrom(children.next(), childPolicy);
+			}
+        }
+    }
+
+    /**
+     * Queries the user whether the resource with the specified path should be
+     * overwritten by a file system object that is being imported.
+     * 
+     * @param resourcePath the workspace path of the resource that needs to be overwritten
+     * @return <code>true</code> to overwrite, <code>false</code> to not overwrite
+     * @exception OperationCanceledException if canceled
+     */
+    boolean queryOverwrite(IPath resourcePath)
+            throws OperationCanceledException {
+        String overwriteAnswer = overwriteCallback.queryOverwrite(resourcePath
+                .makeRelative().toString());
+
+        if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) {
+			throw new OperationCanceledException(messages.ImportOperation_EmptyString());
+		}
+
+        if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
+            return false;
+        }
+
+        if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
+            this.overwriteState = OVERWRITE_NONE;
+            return false;
+        }
+
+        if (overwriteAnswer.equals(IOverwriteQuery.ALL)) {
+			this.overwriteState = OVERWRITE_ALL;
+		}
+
+        return true;
+    }
+
+    /**
+     * Returns whether the given file should be overwritten.
+     *
+     * @param targetFile the file to ask to overwrite 
+     * @param policy determines if the user is queried for overwrite 
+     * @return <code>true</code> if the file should be overwritten, and
+     * 	<code>false</code> if not.
+     */
+    boolean queryOverwriteFile(IFile targetFile, int policy) {
+        //If force overwrite is on don't bother
+        if (policy != POLICY_FORCE_OVERWRITE) {
+            if (this.overwriteState == OVERWRITE_NOT_SET
+                    && !queryOverwrite(targetFile.getFullPath())) {
+				return false;
+			}
+            if (this.overwriteState == OVERWRITE_NONE) {
+				return false;
+			}
+        }
+        return true;
+    }
+
+    /**
+     * Sets the context for use by the VCM provider to prompt the user
+     * for check-out of files.
+     * 
+     * @param shell context for use by the VCM provider to prompt user
+     * 	for check-out. The user will not be prompted if set to <code>null</code>.
+     * @see IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object)
+     * @since 2.1
+     */
+    public void setContext(Shell shell) {
+        context = shell;
+    }
+
+    /**
+     * Sets whether the containment structures that are implied from the full paths
+     * of file system objects being imported should be duplicated in the workbench.
+     *
+     * @param value <code>true</code> if containers should be created, and
+     *  <code>false</code> otherwise
+     */
+    public void setCreateContainerStructure(boolean value) {
+        createContainerStructure = value;
+    }
+
+    /**
+     * Sets the file system objects to import.
+     *
+     * @param filesToImport the list of file system objects to be imported
+     *   (element type: <code>Object</code>)
+     */
+    public void setFilesToImport(List<?> filesToImport) {
+        this.selectedFiles = filesToImport;
+    }
+
+    /**
+     * Sets whether imported file system objects should automatically overwrite
+     * existing workbench resources when a conflict occurs.
+     *
+     * @param value <code>true</code> to automatically overwrite, and 
+     *   <code>false</code> otherwise
+     */
+    public void setOverwriteResources(boolean value) {
+        if (value) {
+			this.overwriteState = OVERWRITE_ALL;
+		}
+    }
+
+    /**
+     * Validates that the given source resources can be copied to the 
+     * destination as decided by the VCM provider.
+     * 
+     * @param existingFiles existing files to validate
+     * @return list of rejected files as absolute paths. Object type IPath.
+     */
+    ArrayList<IPath> validateEdit(List<IFile> existingFiles) {
+       
+        if (existingFiles.size() > 0) {
+            IFile[] files = existingFiles
+                    .toArray(new IFile[existingFiles.size()]);
+            IWorkspace workspace = ResourcesPlugin.getWorkspace();
+            IStatus status = workspace.validateEdit(files, context);
+
+            //If there was a mix return the bad ones
+            if (status.isMultiStatus()) {
+				return getRejectedFiles(status, files);
+			}
+            
+           if(!status.isOK()){
+           		//If just a single status reject them all
+           		errorTable.add(status);
+           		ArrayList<IPath> filteredFiles = new ArrayList<IPath>();
+
+           		for (int i = 0; i < files.length; i++) {
+           			filteredFiles.add(files[i].getFullPath());
+           		}
+           		return filteredFiles;
+           }
+            
+        }
+        return new ArrayList<IPath>();
+    }
+
+    /**
+     * Validates the given file system objects.
+     * The user is prompted to overwrite existing files.
+     * Existing read-only files are validated with the VCM provider.
+     * 
+     * @param sourceFiles files to validate
+     */
+    @SuppressWarnings("unchecked")
+	void validateFiles(List<?> sourceFiles) {
+        ArrayList noOverwrite = new ArrayList();
+        ArrayList overwriteReadonly = new ArrayList();
+
+        collectExistingReadonlyFiles(destinationPath, sourceFiles, noOverwrite,
+                overwriteReadonly, POLICY_DEFAULT);
+        rejectedFiles = validateEdit(overwriteReadonly);
+        rejectedFiles.addAll(noOverwrite);
+    }
+
+    /**
+     * Set Whether groups and links will be created instead of files and folders
+     * 
+     * @param virtualFolders
+     * @since 3.6
+     */
+    public void setVirtualFolders(boolean virtualFolders) {
+        createVirtualFolder = virtualFolders;
+    }
+
+    /**
+     * Set Whether links will be created instead of files and folders
+     * 
+     * @param links
+     * @since 3.6
+     */
+    public void setCreateLinks(boolean links) {
+        createLinks = links;
+    }
+
+    /**
+     * Set a variable relative to which the links are created
+     * 
+     * @param variable
+     * @since 3.6
+     */
+    public void setRelativeVariable(String variable) {
+        relativeVariable = variable;
+    }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.java
new file mode 100644
index 0000000..d159115
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+public interface Messages {
+	public String WizardProjectsImportPage_ProjectLabel();
+	public String WizardProjectsImportPage_ImportProjectsTitle();
+	public String WizardProjectsImportPage_ImportProjectsDescription();
+	public String WizardProjectsImportPage_CopyProjectsIntoWorkspace();
+	public String WizardProjectsImportPage_ProjectsListTitle();
+	public String WizardProjectsImportPage_RootSelectTitle();
+	public String WizardProjectsImportPage_ArchiveSelectTitle();
+	public String WizardProjectsImportPage_SearchingMessage();
+	public String WizardProjectsImportPage_ProcessingMessage();
+	public String WizardProjectsImportPage_ProjectsInWorkspace();
+	public String WizardProjectsImportPage_NoProjectsToImport();
+	public String WizardProjectsImportPage_CheckingMessage();
+	public String WizardProjectsImportPage_SelectDialogTitle();
+	public String WizardProjectsImportPage_SelectArchiveDialogTitle();
+	public String WizardProjectsImportPage_CreateProjectsTask();
+	
+	public String WizardProjectsImportPage_SelectAll();
+	public String WizardProjectsImportPage_DeselectAll();
+	public String WizardProjectsImportPage_Refresh();
+	public String WizardProjectsImportPage_browse();
+	
+	public String WizardExternalProjectImportPage_ErrorMessage();
+	
+	
+	public String ImportOperation_ImportTask();
+	public String ImportOperation_EmptyString();
+	public String ImportOperation_importProblems();
+	public String ImportOperation_coreImportError();
+	public String ImportOperation_targetSameAsSourceError();
+	public String ImportOperation_openStreamError();
+	public String ImportOperation_closeStreamError();
+	public String ImportOperation_cannotCopy();
+	
+	public String ZipImport_badFormat();
+	public String ZipImport_couldNotRead();
+	public String ZipImport_couldNotClose();
+	
+	public String TarImport_invalid_tar_format();
+	public String TarImport_badFormat();
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.properties b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.properties
new file mode 100644
index 0000000..375b498
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.properties
@@ -0,0 +1,37 @@
+WizardProjectsImportPage_RootSelectTitle=Select roo&t directory:
+WizardProjectsImportPage_ArchiveSelectTitle=Select &archive file:
+WizardProjectsImportPage_SelectArchiveDialogTitle=Select archive containing the projects to import
+WizardProjectsImportPage_ProjectsListTitle=&Projects:
+WizardProjectsImportPage_ProcessingMessage=Processing results
+WizardProjectsImportPage_SelectDialogTitle=Select root directory of the projects to import
+WizardProjectsImportPage_SearchingMessage=Searching for projects
+WizardProjectsImportPage_ImportProjectsTitle=Import Projects
+WizardProjectsImportPage_ProjectsInWorkspace=Some projects cannot be imported because they already exist in the workspace
+WizardProjectsImportPage_NoProjectsToImport=No projects are found to import
+WizardProjectsImportPage_CreateProjectsTask=Creating Projects
+WizardProjectsImportPage_ImportProjectsDescription=Select a directory to search for existing Eclipse projects.
+WizardProjectsImportPage_CheckingMessage= Checking: {0}
+WizardProjectsImportPage_CopyProjectsIntoWorkspace=&Copy projects into workspace
+WizardProjectsImportPage_ProjectLabel={0} ({1})
+WizardProjectsImportPage_SelectAll=&Select All
+WizardProjectsImportPage_DeselectAll=&Deselect All
+WizardProjectsImportPage_Refresh=R&efresh
+WizardProjectsImportPage_browse=B&rowse...
+
+WizardExternalProjectImportPage_ErrorMessage = Creation Problems
+
+ImportOperation_ImportTask=Importing:
+ImportOperation_EmptyString=
+ImportOperation_cannotCopy = Cannot copy root file system.
+ImportOperation_importProblems = Problems were encountered during import:
+ImportOperation_openStreamError = Error opening input stream for {0}
+ImportOperation_closeStreamError = Could not close input stream for {0}
+ImportOperation_coreImportError = Unable to import {0}.  Reason: {1}
+ImportOperation_targetSameAsSourceError = Unable to import {0}. The file cannot be copied onto itself
+
+ZipImport_couldNotClose = Could not close file {0}
+ZipImport_badFormat = Source file is not a valid Zip file.
+ZipImport_couldNotRead = Source file could not be read.
+
+TarImport_badFormat = Source file is not a valid tar file.
+TarImport_invalid_tar_format = Not a valid tar format
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarEntry.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarEntry.java
new file mode 100644
index 0000000..5d0034e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarEntry.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+/**
+ * Representation of a file in a tar archive.
+ * 
+ * @since 3.1
+ */
+public class TarEntry implements Cloneable
+{	
+	private String name;
+	private long mode, time, size;
+	private int type;
+	int filepos;
+
+	/**
+	 * Entry type for normal files.
+	 */
+	public static final int FILE = '0';
+
+	/**
+	 * Entry type for directories.
+	 */
+	public static final int DIRECTORY = '5';
+	
+	/**
+	 * Create a new TarEntry for a file of the given name at the
+	 * given position in the file.
+	 * 
+	 * @param name filename
+	 * @param pos position in the file in bytes
+	 */
+	TarEntry(String name, int pos) {
+		this.name = name;
+		mode = 0644;
+		type = FILE;
+		filepos = pos;
+		time = System.currentTimeMillis() / 1000;
+	}
+
+	/**
+	 * Create a new TarEntry for a file of the given name.
+	 * 
+	 * @param name filename
+	 */
+	public TarEntry(String name) {
+		this(name, -1);
+	}
+
+	/**
+	 * Returns the type of this file, one of FILE, LINK, SYM_LINK,
+	 * CHAR_DEVICE, BLOCK_DEVICE, DIRECTORY or FIFO.
+	 * 
+	 * @return file type
+	 */
+	public int getFileType() {
+		return type;
+	}
+
+	/**
+	 * Returns the mode of the file in UNIX permissions format.
+	 * 
+	 * @return file mode
+	 */
+	public long getMode() {
+		return mode;
+	}
+
+	/**
+	 * Returns the name of the file.
+	 * 
+	 * @return filename
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Returns the size of the file in bytes.
+	 * 
+	 * @return filesize
+	 */
+	public long getSize() {
+		return size;
+	}
+
+	/**
+	 * Returns the modification time of the file in seconds since January
+	 * 1st 1970.
+	 * 
+	 * @return time
+	 */
+	public long getTime() {
+		return time;
+	}
+
+	/**
+	 * Sets the type of the file, one of FILE, LINK, SYMLINK, CHAR_DEVICE,
+	 * BLOCK_DEVICE, or DIRECTORY.
+	 * 
+	 * @param type
+	 */
+	public void setFileType(int type) {
+		this.type = type;
+	}
+
+	/**
+	 * Sets the mode of the file in UNIX permissions format.
+	 * 
+	 * @param mode
+	 */
+	public void setMode(long mode) {
+		this.mode = mode;
+	}
+
+	/**
+	 * Sets the size of the file in bytes.
+	 * 
+	 * @param size
+	 */
+	public void setSize(long size) {
+		this.size = size;
+	}
+
+	/**
+	 * Sets the modification time of the file in seconds since January
+	 * 1st 1970.
+	 * 
+	 * @param time
+	 */
+	public void setTime(long time) {
+		this.time = time;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarException.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarException.java
new file mode 100644
index 0000000..c4ecc48
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarException.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+/**
+ * Exception generated upon encountering corrupted tar files.
+ */
+public class TarException extends Exception {
+	/**
+	 * Generated serial version UID for this class.
+	 */
+	private static final long serialVersionUID = 2886671254518853528L;
+
+    /**
+     * Constructs a TarException without a detail string.
+     */
+    public TarException() {
+    	super();
+    }
+	
+	/**
+     * Constructs a TarException with the specified detail string.
+     *
+     * @param s the detail string
+     */
+    public TarException(String s) {
+    	super(s);
+    }
+	
+    /**
+     * Constructs a TarException with the specified detail string.
+     *
+     * @param s the detail string
+     * @param cause the cause
+     */
+    public TarException(String s, Throwable cause) {
+    	super(s, cause);
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarFile.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarFile.java
new file mode 100644
index 0000000..bfc342b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarFile.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Remy Chi Jian Suen <remy.suen@gmail.com> - Bug 243347 TarFile should not throw NPE in finalize()
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.zip.GZIPInputStream;
+
+
+/**
+ * Reads a .tar or .tar.gz archive file, providing an index enumeration
+ * and allows for accessing an InputStream for arbitrary files in the
+ * archive.
+ * 
+ * @since 3.1
+ */
+public class TarFile {
+	private File file;
+	private TarInputStream entryEnumerationStream;
+	private TarEntry curEntry;
+	private TarInputStream entryStream;
+
+	private InputStream internalEntryStream;
+	private Messages messages;
+	
+	/**
+	 * Create a new TarFile for the given file.
+	 * 
+	 * @param file
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	public TarFile(File file, Messages messages) throws TarException, IOException {
+		this.file = file;
+		this.messages = messages;
+
+		InputStream in = new FileInputStream(file);
+		// First, check if it's a GZIPInputStream.
+		try {
+			in = new GZIPInputStream(in);
+		} catch(IOException e) {
+			//If it is not compressed we close
+			//the old one and recreate
+			in.close();
+			in = new FileInputStream(file);
+		}
+		try {
+			entryEnumerationStream = new TarInputStream(in, messages);
+		} catch (TarException ex) {
+			in.close();
+			throw ex;
+		}
+		curEntry = entryEnumerationStream.getNextEntry();
+	}
+	
+	/**
+	 * Close the tar file input stream.
+	 * 
+	 * @throws IOException if the file cannot be successfully closed
+	 */
+	public void close() throws IOException {
+		if (entryEnumerationStream != null)
+			entryEnumerationStream.close();
+		if (internalEntryStream != null)
+			internalEntryStream.close();
+	}
+
+	/**
+	 * Create a new TarFile for the given path name.
+	 * 
+	 * @param filename
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	public TarFile(String filename, Messages messages) throws TarException, IOException {
+		this(new File(filename),messages);
+	}
+
+	/**
+	 * Returns an enumeration cataloguing the tar archive.
+	 * 
+	 * @return enumeration of all files in the archive
+	 */
+	public Enumeration<TarEntry> entries() {
+		return new Enumeration<TarEntry>() {
+			public boolean hasMoreElements() {
+				return (curEntry != null);
+			}
+			
+			public TarEntry nextElement() {
+				TarEntry oldEntry = curEntry;
+				try {
+					curEntry = entryEnumerationStream.getNextEntry();
+				} catch(TarException e) {
+					curEntry = null;
+				} catch(IOException e) {
+					curEntry = null;
+				}
+				return oldEntry;
+			}
+		};
+	}
+
+	/**
+	 * Returns a new InputStream for the given file in the tar archive.
+	 * 
+	 * @param entry
+	 * @return an input stream for the given file
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	public InputStream getInputStream(TarEntry entry) throws TarException, IOException {
+		if(entryStream == null || !entryStream.skipToEntry(entry)) {
+			if (internalEntryStream != null) {
+				internalEntryStream.close();
+			}
+			internalEntryStream = new FileInputStream(file);
+			// First, check if it's a GZIPInputStream.
+			try {
+				internalEntryStream = new GZIPInputStream(internalEntryStream);
+			} catch(IOException e) {
+				//If it is not compressed we close
+				//the old one and recreate
+				internalEntryStream.close();
+				internalEntryStream = new FileInputStream(file);
+			}
+			entryStream = new TarInputStream(internalEntryStream, entry, messages) {
+				public void close() {
+					// Ignore close() since we want to reuse the stream.
+				}
+			};
+		}
+		return entryStream;
+	}
+
+	/**
+	 * Returns the path name of the file this archive represents.
+	 * 
+	 * @return path
+	 */
+	public String getName() {
+		return file.getPath();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.zip.ZipFile#finalize()
+	 * 
+	 */
+	protected void finalize() throws Throwable {
+		close();
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarInputStream.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarInputStream.java
new file mode 100644
index 0000000..c770520
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarInputStream.java
@@ -0,0 +1,346 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Input stream for reading files in ustar format (tar) compatible
+ * with the specification in IEEE Std 1003.1-2001.  Also supports
+ * long filenames encoded using the GNU @LongLink extension.
+ * 
+ * @since 3.1
+ */
+public class TarInputStream extends FilterInputStream
+{
+	private int nextEntry = 0;
+	private int nextEOF = 0;
+	private int filepos = 0;
+	private int bytesread = 0;
+	private TarEntry firstEntry = null;
+	private String longLinkName = null;
+	private Messages messages;
+
+	/**
+	 * Creates a new tar input stream on the given input stream.
+	 * 
+	 * @param in input stream
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	public TarInputStream(InputStream in, Messages messages) throws TarException, IOException {
+		super(in);
+		this.messages = messages;
+		// Read in the first TarEntry to make sure
+		// the input is a valid tar file stream.
+		firstEntry = getNextEntry();
+	}
+
+	/**
+	 * Create a new tar input stream, skipping ahead to the given entry
+	 * in the file.
+	 * 
+	 * @param in input stream
+	 * @param entry skips to this entry in the file
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	TarInputStream(InputStream in, TarEntry entry, Messages messages) throws TarException, IOException {
+		super(in);
+		this.messages = messages;
+		skipToEntry(entry);
+	}
+
+	/**
+	 *  The checksum of a tar file header is simply the sum of the bytes in
+	 *  the header.
+	 * 
+	 * @param header
+	 * @return checksum
+	 */
+	private long headerChecksum(byte[] header) {
+		long sum = 0;
+		for(int i = 0; i < 512; i++) {
+			sum += header[i] & 0xff;
+		}
+		return sum;
+	}
+
+	/**
+	 * Skips ahead to the position of the given entry in the file.
+	 * 
+	 * @param entry
+	 * @returns false if the entry has already been passed
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	boolean skipToEntry(TarEntry entry) throws TarException, IOException {
+		int bytestoskip = entry.filepos - bytesread;
+		if(bytestoskip < 0) {
+			return false;
+		}
+		while(bytestoskip > 0) {
+			long ret = in.skip(bytestoskip);
+			if(ret < 0) {
+				throw new IOException("early end of stream"); //$NON-NLS-1$
+			}
+			bytestoskip -= ret;
+			bytesread += ret;
+		}
+		filepos = entry.filepos;
+		nextEntry = 0;
+		nextEOF = 0;
+		// Read next header to seek to file data.
+		getNextEntry();
+		return true;
+	}
+
+	/**
+	 * Returns true if the header checksum is correct.
+	 * 
+	 * @param header
+	 * @return true if this header has a valid checksum
+	 */
+	private boolean isValidTarHeader(byte[] header) {
+		long fileChecksum, calculatedChecksum;
+		int pos, i;
+		
+		pos = 148;
+		StringBuffer checksumString = new StringBuffer();
+		for(i = 0; i < 8; i++) {
+			if(header[pos + i] == ' ') {
+				continue;
+			}
+			if(header[pos + i] == 0 || !Character.isDigit((char) header[pos + i])) {
+				break;
+			}
+			checksumString.append((char) header[pos + i]);
+		}
+		if(checksumString.length() == 0) {
+			return false;
+		}
+		if(checksumString.charAt(0) != '0') {
+			checksumString.insert(0, '0');
+		}
+		try {
+			fileChecksum = Long.decode(checksumString.toString()).longValue();
+		} catch(NumberFormatException exception) {
+			//This is not valid if it cannot be parsed
+			return false;
+		}
+
+		// Blank out the checksum.
+		for(i = 0; i < 8; i++) {
+			header[pos + i] = ' ';
+		}
+		calculatedChecksum = headerChecksum(header);
+
+		return (fileChecksum == calculatedChecksum);
+	}
+
+	/**
+	 * Returns the next entry in the tar file.  Does not handle
+	 * GNU @LongLink extensions.
+	 * 
+	 * @return the next entry in the tar file
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	TarEntry getNextEntryInternal() throws TarException, IOException {
+		byte[] header = new byte[512];
+		int pos = 0;
+		int i;
+
+		if(firstEntry != null) {
+			TarEntry entryReturn = firstEntry;
+			firstEntry = null;
+			return entryReturn;
+		}
+
+		while(nextEntry > 0) {
+			long ret = in.skip(nextEntry);
+			if(ret < 0) {
+				throw new IOException("early end of stream"); //$NON-NLS-1$
+			}
+			nextEntry -= ret;
+			bytesread += ret;
+		}
+
+		int bytestoread = 512;
+		while(bytestoread > 0) {
+			int ret = super.read(header, 512 - bytestoread, bytestoread);
+			if( ret < 0 ) {
+				throw new IOException("early end of stream"); //$NON-NLS-1$
+			}
+			bytestoread -= ret;
+			bytesread += ret;
+		}
+
+		// If we have a header of all zeros, this marks the end of the file.
+		if(headerChecksum(header) == 0) {
+			// We are at the end of the file.
+			if(filepos > 0) {
+				return null;
+			}
+			
+			// Invalid stream.
+			throw new TarException("not in tar format"); //$NON-NLS-1$
+		}
+		
+		// Validate checksum.
+		if(!isValidTarHeader(header)) {
+			throw new TarException("not in tar format"); //$NON-NLS-1$
+		}
+
+		while (pos < 100 && header[pos] != 0) {
+			pos++;
+		}
+		String name = new String(header, 0, pos, "UTF8"); //$NON-NLS-1$
+		// Prepend the prefix here.
+		pos = 345;
+		if(header[pos] != 0) {
+			while (pos < 500 && header[pos] != 0) {
+				pos++;
+			}
+			String prefix = new String(header, 345, pos - 345, "UTF8"); //$NON-NLS-1$
+			name = prefix + "/" + name; //$NON-NLS-1$
+		}
+		
+		TarEntry entry;
+		if(longLinkName != null) {
+			entry = new TarEntry(longLinkName, filepos);
+			longLinkName = null;
+		} else {
+			entry = new TarEntry(name, filepos);
+		}
+		if(header[156] != 0) {
+			entry.setFileType(header[156]);
+		}
+		
+		pos = 100;
+		StringBuffer mode = new StringBuffer();
+		for(i = 0; i < 8; i++) {
+			if(header[pos + i] == 0) {
+				break;
+			}
+			if(header[pos + i] == ' ') {
+				continue;
+			}
+			mode.append((char) header[pos + i]);
+		}
+		if(mode.length() > 0 && mode.charAt(0) != '0') {
+			mode.insert(0, '0');
+		}
+		try {
+			long fileMode = Long.decode(mode.toString()).longValue();
+			entry.setMode(fileMode);
+		} catch(NumberFormatException nfe) {
+			throw new TarException(messages.TarImport_invalid_tar_format(), nfe);
+		}
+		
+		pos = 100 + 24;
+		StringBuffer size = new StringBuffer();
+		for(i = 0; i < 12; i++) {
+			if(header[pos + i] == 0) {
+				break;
+			}
+			if(header[pos + i] == ' ') {
+				continue;
+			}
+			size.append((char) header[pos + i]);
+		}
+		if(size.charAt(0) != '0') {
+			size.insert(0, '0');
+		}
+		int fileSize;
+		try {
+			fileSize = Integer.decode(size.toString()).intValue();
+		} catch(NumberFormatException nfe) {
+			throw new TarException(messages.TarImport_invalid_tar_format(), nfe);
+		}
+
+		entry.setSize(fileSize);
+		nextEOF = fileSize;
+		if(fileSize % 512 > 0) {
+			nextEntry = fileSize + (512 - (fileSize % 512));
+		} else {
+			nextEntry = fileSize;
+		}
+		filepos += (nextEntry + 512);
+		return entry;
+	}
+
+	/**
+	 * Moves ahead to the next file in the tar archive and returns
+	 * a TarEntry object describing it.
+	 * 
+	 * @return the next entry in the tar file
+	 * @throws TarException
+	 * @throws IOException
+	 */
+	public TarEntry getNextEntry() throws TarException, IOException {
+		TarEntry entry = getNextEntryInternal();
+
+		if(entry != null && entry.getName().equals("././@LongLink")) { //$NON-NLS-1$
+			// This is a GNU extension for doing long filenames.
+			// We get a file called ././@LongLink which just contains
+			// the real pathname.
+			byte[] longNameData = new byte[(int) entry.getSize()];
+			int bytesread = 0;
+			while (bytesread < longNameData.length) {
+				int cur = read(longNameData, bytesread, longNameData.length - bytesread);
+				if (cur < 0) {
+					throw new IOException("early end of stream"); //$NON-NLS-1$
+				}
+				bytesread += cur;
+			}
+
+			int pos = 0;
+			while (pos < longNameData.length && longNameData[pos] != 0) {
+				pos++;
+			}
+			longLinkName = new String(longNameData, 0, pos, "UTF8"); //$NON-NLS-1$
+			return getNextEntryInternal();
+		}
+		return entry;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.FilterInputStream#read(byte[], int, int)
+	 */
+	public int read(byte[] b, int off, int len) throws IOException {
+		if(nextEOF == 0) {
+			return -1;
+		}
+		if(len > nextEOF) {
+			len = nextEOF;
+		}
+		int size = super.read(b, off, len);
+		nextEntry -= size;
+		nextEOF -= size;
+		bytesread += size;
+		return size;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.FilterInputStream#read()
+	 */
+	public int read() throws IOException {
+		byte[] data = new byte[1];
+		int size = read(data, 0, 1);
+		if (size < 0) {
+			return size;
+		}
+		return data[0];
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarLeveledStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarLeveledStructureProvider.java
new file mode 100644
index 0000000..44e9eb3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarLeveledStructureProvider.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Red Hat, Inc - Was TarFileStructureProvider, performed changes from 
+ *     IImportStructureProvider to ILeveledImportStructureProvider
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.services.log.Logger;
+
+/**
+ * This class provides information regarding the context structure and content
+ * of specified tar file entry objects.
+ * 
+ * @since 3.1
+ */
+public class TarLeveledStructureProvider implements
+		ILeveledImportStructureProvider {
+	private TarFile tarFile;
+
+	private TarEntry root = new TarEntry("/");//$NON-NLS-1$
+
+	private Map<TarEntry,List<TarEntry>> children;
+
+	private Map<IPath,TarEntry> directoryEntryCache = new HashMap<IPath,TarEntry>();
+
+	private int stripLevel;
+	
+	private Logger logger;
+	
+	private Messages messages;
+
+	/**
+	 * Creates a <code>TarFileStructureProvider</code>, which will operate on
+	 * the passed tar file.
+	 * 
+	 * @param sourceFile
+	 *            the source TarFile
+	 */
+	public TarLeveledStructureProvider(TarFile sourceFile, Logger logger, Messages messages) {
+		super();
+		this.messages = messages;
+		this.logger = logger;
+		tarFile = sourceFile;
+		root.setFileType(TarEntry.DIRECTORY);
+	}
+
+	/**
+	 * Creates a new container tar entry with the specified name, iff it has 
+	 * not already been created. If the parent of the given element does not
+	 * already exist it will be recursively created as well.
+	 * @param pathname The path representing the container
+	 * @return The element represented by this pathname (it may have already existed)
+	 */
+	protected TarEntry createContainer(IPath pathname) {
+		TarEntry existingEntry = (TarEntry) directoryEntryCache.get(pathname);
+		if (existingEntry != null) {
+			return existingEntry;
+		}
+
+		TarEntry parent;
+		if (pathname.segmentCount() == 1) {
+			parent = root;
+		} else {
+			parent = createContainer(pathname.removeLastSegments(1));
+		}
+		TarEntry newEntry = new TarEntry(pathname.toString());
+		newEntry.setFileType(TarEntry.DIRECTORY);
+		directoryEntryCache.put(pathname, newEntry);
+		List<TarEntry> childList = new ArrayList<TarEntry>();
+		children.put(newEntry, childList);
+
+		List<TarEntry> parentChildList = children.get(parent);
+		parentChildList.add(newEntry);
+		return newEntry;
+	}
+
+	/**
+	 * Creates a new tar file entry with the specified name.
+	 */
+	protected void createFile(TarEntry entry) {
+		IPath pathname = new Path(entry.getName());
+		TarEntry parent;
+		if (pathname.segmentCount() == 1) {
+			parent = root;
+		} else {
+			parent = (TarEntry) directoryEntryCache.get(pathname
+					.removeLastSegments(1));
+		}
+
+		List<TarEntry> childList = children.get(parent);
+		childList.add(entry);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public List<TarEntry> getChildren(Object element) {
+		if (children == null) {
+			initialize();
+		}
+
+		return children.get(element);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public InputStream getContents(Object element) {
+		try {
+			return tarFile.getInputStream((TarEntry) element);
+		} catch (TarException e) {
+			logger.error(e);
+//			IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+			return null;
+		} catch (IOException e) {
+			logger.error(e);
+//			IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+			return null;
+		}
+	}
+
+	/**
+	 * Returns the resource attributes for this file.
+	 * 
+	 * @param element
+	 * @return the attributes of the file
+	 */
+	public ResourceAttributes getResourceAttributes(Object element) {
+		ResourceAttributes attributes = new ResourceAttributes();
+		TarEntry entry = (TarEntry) element;
+		attributes.setExecutable((entry.getMode() & 0100) != 0);
+		attributes.setReadOnly((entry.getMode() & 0200) == 0);
+		return attributes;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public String getFullPath(Object element) {
+		return stripPath(((TarEntry) element).getName());
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public String getLabel(Object element) {
+		if (element.equals(root)) {
+			return ((TarEntry) element).getName();
+		}
+
+		return stripPath(new Path(((TarEntry) element).getName()).lastSegment());
+	}
+
+	/**
+	 * Returns the entry that this importer uses as the root sentinel.
+	 * 
+	 * @return TarEntry entry
+	 */
+	public Object getRoot() {
+		return root;
+	}
+
+	/**
+	 * Returns the tar file that this provider provides structure for.
+	 * 
+	 * @return TarFile file
+	 */
+	public TarFile getTarFile() {
+		return tarFile;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider#closeArchive()
+	 */
+	public boolean closeArchive(){
+		try {
+			getTarFile().close();
+		} catch (IOException e) {
+			logger.error(e, messages.ZipImport_couldNotClose()
+					+ getTarFile().getName());
+//			IDEWorkbenchPlugin.log(DataTransferMessages.ZipImport_couldNotClose
+//					+ getTarFile().getName(), e);
+			return false;
+		}
+		return true;
+	}
+	
+	/**
+	 * Initializes this object's children table based on the contents of the
+	 * specified source file.
+	 */
+	protected void initialize() {
+		children = new HashMap<TarEntry,List<TarEntry>>(1000);
+		
+		children.put(root, new ArrayList<TarEntry>());
+		Enumeration<TarEntry> entries = tarFile.entries();
+		while (entries.hasMoreElements()) {
+			TarEntry entry = (TarEntry) entries.nextElement();
+			IPath path = new Path(entry.getName()).addTrailingSeparator();
+			
+			if (entry.getFileType() == TarEntry.DIRECTORY) {
+				createContainer(path);
+			} else
+			{
+				// Ensure the container structure for all levels above this is initialized
+				// Once we hit a higher-level container that's already added we need go no further
+				int pathSegmentCount = path.segmentCount();
+				if (pathSegmentCount > 1) {
+					createContainer(path.uptoSegment(pathSegmentCount - 1));
+				}
+				createFile(entry);
+			}
+		}
+	}
+	
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public boolean isFolder(Object element) {
+		return (((TarEntry) element).getFileType() == TarEntry.DIRECTORY);
+	}
+
+	/*
+	 * Strip the leading directories from the path
+	 */
+	private String stripPath(String path) {
+		String pathOrig = new String(path);
+		for (int i = 0; i < stripLevel; i++) {
+			int firstSep = path.indexOf('/');
+			// If the first character was a seperator we must strip to the next
+			// seperator as well
+			if (firstSep == 0) {
+				path = path.substring(1);
+				firstSep = path.indexOf('/');
+			}
+			// No seperator wasw present so we're in a higher directory right
+			// now
+			if (firstSep == -1) {
+				return pathOrig;
+			}
+			path = path.substring(firstSep);
+		}
+		return path;
+	}
+
+	public void setStrip(int level) {
+		stripLevel = level;
+	}
+
+	public int getStrip() {
+		return stripLevel;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/WizardProjectsImportPage.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/WizardProjectsImportPage.java
new file mode 100644
index 0000000..c49772e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/WizardProjectsImportPage.java
@@ -0,0 +1,1647 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Red Hat, Inc - extensive changes to allow importing of Archive Files
+ *     Philippe Ombredanne (pombredanne@nexb.com)
+ *     		- Bug 101180 [Import/Export] Import Existing Project into Workspace default widget is back button , should be text field
+ *     Martin Oberhuber (martin.oberhuber@windriver.com)
+ *     		- Bug 187318[Wizards] "Import Existing Project" loops forever with cyclic symbolic links
+ *     Remy Chi Jian Suen  (remy.suen@gmail.com)
+ *     		- Bug 210568 [Import/Export] [Import/Export] - Refresh button does not update list of projects
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.actions.WorkspaceModifyOperation;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs.IOverwriteQuery;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.PixelConverter;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * The WizardProjectsImportPage is the page that allows the user to import
+ * projects from a particular location.
+ */
+public class WizardProjectsImportPage extends WizardPage implements
+		IOverwriteQuery {
+
+	/**
+	 * The name of the folder containing metadata information for the workspace.
+	 */
+	public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
+
+	/**
+	 * The import structure provider.
+	 * 
+	 * @since 3.4
+	 */
+	private ILeveledImportStructureProvider structureProvider;
+
+	/**
+	 * @since 3.5
+	 * 
+	 */
+	private final class ProjectLabelProvider extends LabelProvider implements
+			IColorProvider {
+
+		public String getText(Object element) {
+			return ((ProjectRecord) element).getProjectLabel();
+		}
+
+		public Color getBackground(Object element) {
+			return null;
+		}
+
+		public Color getForeground(Object element) {
+			ProjectRecord projectRecord = (ProjectRecord) element;
+			if (projectRecord.hasConflicts)
+				return getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY);
+			return null;
+		}
+	}
+
+	/**
+	 * Class declared public only for test suite.
+	 * 
+	 */
+	public class ProjectRecord {
+		File projectSystemFile;
+
+		Object projectArchiveFile;
+
+		String projectName;
+
+		Object parent;
+
+		int level;
+
+		boolean hasConflicts;
+
+		IProjectDescription description;
+
+		/**
+		 * Create a record for a project based on the info in the file.
+		 * 
+		 * @param file
+		 */
+		ProjectRecord(File file) {
+			projectSystemFile = file;
+			setProjectName();
+		}
+
+		/**
+		 * @param file
+		 *            The Object representing the .project file
+		 * @param parent
+		 *            The parent folder of the .project file
+		 * @param level
+		 *            The number of levels deep in the provider the file is
+		 */
+		ProjectRecord(Object file, Object parent, int level) {
+			this.projectArchiveFile = file;
+			this.parent = parent;
+			this.level = level;
+			setProjectName();
+		}
+
+		/**
+		 * Set the name of the project based on the projectFile.
+		 */
+		private void setProjectName() {
+			try {
+				if (projectArchiveFile != null) {
+					InputStream stream = structureProvider
+							.getContents(projectArchiveFile);
+
+					// If we can get a description pull the name from there
+					if (stream == null) {
+						if (projectArchiveFile instanceof ZipEntry) {
+							IPath path = new Path(
+									((ZipEntry) projectArchiveFile).getName());
+							projectName = path.segment(path.segmentCount() - 2);
+						} else if (projectArchiveFile instanceof TarEntry) {
+							IPath path = new Path(
+									((TarEntry) projectArchiveFile).getName());
+							projectName = path.segment(path.segmentCount() - 2);
+						}
+					} else {
+						description = workspace.loadProjectDescription(stream);
+						stream.close();
+						projectName = description.getName();
+					}
+
+				}
+
+				// If we don't have the project name try again
+				if (projectName == null) {
+					IPath path = new Path(projectSystemFile.getPath());
+					// if the file is in the default location, use the directory
+					// name as the project name
+					if (isDefaultLocation(path)) {
+						projectName = path.segment(path.segmentCount() - 2);
+						description = workspace
+								.newProjectDescription(projectName);
+					} else {
+						description = workspace.loadProjectDescription(path);
+						projectName = description.getName();
+					}
+
+				}
+			} catch (CoreException e) {
+				// no good couldn't get the name
+			} catch (IOException e) {
+				// no good couldn't get the name
+			}
+		}
+
+		/**
+		 * Returns whether the given project description file path is in the
+		 * default location for a project
+		 * 
+		 * @param path
+		 *            The path to examine
+		 * @return Whether the given path is the default location for a project
+		 */
+		private boolean isDefaultLocation(IPath path) {
+			// The project description file must at least be within the project,
+			// which is within the workspace location
+			if (path.segmentCount() < 2)
+				return false;
+			return path.removeLastSegments(2).toFile()
+					.equals(Platform.getLocation().toFile());
+		}
+
+		/**
+		 * Get the name of the project
+		 * 
+		 * @return String
+		 */
+		public String getProjectName() {
+			return projectName;
+		}
+
+		/**
+		 * Gets the label to be used when rendering this project record in the
+		 * UI.
+		 * 
+		 * @return String the label
+		 * @since 3.4
+		 */
+		public String getProjectLabel() {
+			if (description == null)
+				return projectName;
+
+			String path = projectSystemFile == null ? structureProvider
+					.getLabel(parent) : projectSystemFile.getParent();
+
+			return NLS.bind(
+					messsagesLookup.WizardProjectsImportPage_ProjectLabel(),
+					projectName, path);
+		}
+
+		/**
+		 * @return Returns the hasConflicts.
+		 */
+		public boolean hasConflicts() {
+			return hasConflicts;
+		}
+	}
+
+	// dialog store id constants
+	private final static String STORE_COPY_PROJECT_ID = "WizardProjectsImportPage.STORE_COPY_PROJECT_ID"; //$NON-NLS-1$
+
+	private final static String STORE_ARCHIVE_SELECTED = "WizardProjectsImportPage.STORE_ARCHIVE_SELECTED"; //$NON-NLS-1$
+
+	private Text directoryPathField;
+
+	private CheckboxTreeViewer projectsList;
+
+	private Button copyCheckbox;
+
+	private boolean copyFiles = false;
+
+	private ProjectRecord[] selectedProjects = new ProjectRecord[0];
+
+	// Keep track of the directory that we browsed to last time
+	// the wizard was invoked.
+	private static String previouslyBrowsedDirectory = ""; //$NON-NLS-1$
+
+	// Keep track of the archive that we browsed to last time
+	// the wizard was invoked.
+	private static String previouslyBrowsedArchive = ""; //$NON-NLS-1$
+
+	private Button projectFromDirectoryRadio;
+
+	private Button projectFromArchiveRadio;
+
+	private Text archivePathField;
+
+	private Button browseDirectoriesButton;
+
+	private Button browseArchivesButton;
+
+	private IProject[] wsProjects;
+
+	// constant from WizardArchiveFileResourceImportPage1
+	private static final String[] FILE_IMPORT_MASK = {
+			"*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+	// The initial path to set
+	private String initialPath;
+
+	// The last selected path to minimize searches
+	private String lastPath;
+	// The last time that the file or folder at the selected path was modified
+	// to mimize searches
+	private long lastModified;
+
+	// TODO SimpleIDE
+	// private WorkingSetGroup workingSetGroup;
+
+	// private IStructuredSelection currentSelection;
+
+	private IWorkspace workspace;
+
+	private Logger logger;
+
+	private StatusReporter statusReporter;
+
+	private Messages messsagesLookup;
+
+	/**
+	 * Creates a new project creation wizard page.
+	 * 
+	 */
+	public WizardProjectsImportPage(IWorkspace workspace,
+			StatusReporter statusReporter, Logger logger,
+			Messages messsagesLookup) {
+		this(
+				"wizardExternalProjectsPage", null, null, workspace, statusReporter, logger, messsagesLookup); //$NON-NLS-1$
+	}
+
+	/**
+	 * Create a new instance of the receiver.
+	 * 
+	 * @param pageName
+	 */
+	public WizardProjectsImportPage(String pageName, IWorkspace workspace,
+			StatusReporter statusReporter, Logger logger,
+			Messages messsagesLookup) {
+		this(pageName, null, null, workspace, statusReporter, logger,
+				messsagesLookup);
+	}
+
+	/**
+	 * More (many more) parameters.
+	 * 
+	 * @param pageName
+	 * @param initialPath
+	 * @param currentSelection
+	 * @since 3.5
+	 */
+	public WizardProjectsImportPage(String pageName, String initialPath,
+			IStructuredSelection currentSelection, IWorkspace workspace,
+			StatusReporter statusReporter, Logger logger,
+			Messages messsagesLookup) {
+		super(pageName);
+		this.messsagesLookup = messsagesLookup;
+		this.logger = logger;
+		this.statusReporter = statusReporter;
+		this.workspace = workspace;
+		this.initialPath = initialPath;
+		// this.currentSelection = currentSelection;
+		setPageComplete(false);
+		setTitle(messsagesLookup.WizardProjectsImportPage_ImportProjectsTitle());
+		setDescription(messsagesLookup
+				.WizardProjectsImportPage_ImportProjectsDescription());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
+	 * .Composite)
+	 */
+	public void createControl(Composite parent) {
+
+		initializeDialogUnits(parent);
+
+		Composite workArea = new Composite(parent, SWT.NONE);
+		setControl(workArea);
+
+		workArea.setLayout(new GridLayout());
+		workArea.setLayoutData(new GridData(GridData.FILL_BOTH
+				| GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+
+		createProjectsRoot(workArea);
+		createProjectsList(workArea);
+		createOptionsArea(workArea);
+		// TODO SimpleIDE createWorkingSetGroup(workArea);
+		restoreWidgetValues();
+		Dialog.applyDialogFont(workArea);
+
+	}
+
+	// TODO SimpleIDE
+	// /**
+	// * @param workArea
+	// */
+	// private void createWorkingSetGroup(Composite workArea) {
+	//		String[] workingSetIds = new String[] {"org.eclipse.ui.resourceWorkingSetPage",  //$NON-NLS-1$
+	//				"org.eclipse.jdt.ui.JavaWorkingSetPage"};  //$NON-NLS-1$
+	// workingSetGroup = new WorkingSetGroup(workArea, currentSelection,
+	// workingSetIds);
+	// }
+
+	/**
+	 * Create the area with the extra options.
+	 * 
+	 * @param workArea
+	 */
+	private void createOptionsArea(Composite workArea) {
+		Composite optionsGroup = new Composite(workArea, SWT.NONE);
+		optionsGroup.setLayout(new GridLayout());
+		optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		copyCheckbox = new Button(optionsGroup, SWT.CHECK);
+		copyCheckbox.setText(messsagesLookup
+				.WizardProjectsImportPage_CopyProjectsIntoWorkspace());
+		copyCheckbox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		copyCheckbox.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				copyFiles = copyCheckbox.getSelection();
+			}
+		});
+	}
+
+	/**
+	 * Create the checkbox list for the found projects.
+	 * 
+	 * @param workArea
+	 */
+	private void createProjectsList(Composite workArea) {
+
+		Label title = new Label(workArea, SWT.NONE);
+		title.setText(messsagesLookup
+				.WizardProjectsImportPage_ProjectsListTitle());
+
+		Composite listComposite = new Composite(workArea, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginWidth = 0;
+		layout.makeColumnsEqualWidth = false;
+		listComposite.setLayout(layout);
+
+		listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+				| GridData.GRAB_VERTICAL | GridData.FILL_BOTH));
+
+		projectsList = new CheckboxTreeViewer(listComposite, SWT.BORDER);
+		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+		gridData.widthHint = new PixelConverter(projectsList.getControl())
+				.convertWidthInCharsToPixels(25);
+		gridData.heightHint = new PixelConverter(projectsList.getControl())
+				.convertHeightInCharsToPixels(10);
+		projectsList.getControl().setLayoutData(gridData);
+		projectsList.setContentProvider(new ITreeContentProvider() {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java
+			 * .lang.Object)
+			 */
+			public Object[] getChildren(Object parentElement) {
+				return null;
+			}
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.viewers.IStructuredContentProvider#getElements
+			 * (java.lang.Object)
+			 */
+			public Object[] getElements(Object inputElement) {
+				return getProjectRecords();
+			}
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java
+			 * .lang.Object)
+			 */
+			public boolean hasChildren(Object element) {
+				return false;
+			}
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java
+			 * .lang.Object)
+			 */
+			public Object getParent(Object element) {
+				return null;
+			}
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+			 */
+			public void dispose() {
+
+			}
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse
+			 * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+			 */
+			public void inputChanged(Viewer viewer, Object oldInput,
+					Object newInput) {
+			}
+
+		});
+
+		projectsList.setLabelProvider(new ProjectLabelProvider());
+
+		projectsList.addCheckStateListener(new ICheckStateListener() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged
+			 * (org.eclipse.jface.viewers.CheckStateChangedEvent)
+			 */
+			public void checkStateChanged(CheckStateChangedEvent event) {
+				ProjectRecord element = (ProjectRecord) event.getElement();
+				if (element.hasConflicts) {
+					projectsList.setChecked(element, false);
+				}
+				setPageComplete(projectsList.getCheckedElements().length > 0);
+			}
+		});
+
+		projectsList.setInput(this);
+		projectsList.setComparator(new ViewerComparator());
+		createSelectionButtons(listComposite);
+	}
+
+	/**
+	 * Create the selection buttons in the listComposite.
+	 * 
+	 * @param listComposite
+	 */
+	private void createSelectionButtons(Composite listComposite) {
+		Composite buttonsComposite = new Composite(listComposite, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		buttonsComposite.setLayout(layout);
+
+		buttonsComposite.setLayoutData(new GridData(
+				GridData.VERTICAL_ALIGN_BEGINNING));
+
+		Button selectAll = new Button(buttonsComposite, SWT.PUSH);
+		selectAll.setText(messsagesLookup.WizardProjectsImportPage_SelectAll());
+		selectAll.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				for (int i = 0; i < selectedProjects.length; i++) {
+					if (selectedProjects[i].hasConflicts)
+						projectsList.setChecked(selectedProjects[i], false);
+					else
+						projectsList.setChecked(selectedProjects[i], true);
+				}
+				setPageComplete(projectsList.getCheckedElements().length > 0);
+			}
+		});
+		Dialog.applyDialogFont(selectAll);
+		setButtonLayoutData(selectAll);
+
+		Button deselectAll = new Button(buttonsComposite, SWT.PUSH);
+		deselectAll.setText(messsagesLookup
+				.WizardProjectsImportPage_DeselectAll());
+		deselectAll.addSelectionListener(new SelectionAdapter() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+			 * .swt.events.SelectionEvent)
+			 */
+			public void widgetSelected(SelectionEvent e) {
+
+				projectsList.setCheckedElements(new Object[0]);
+				setPageComplete(false);
+			}
+		});
+		Dialog.applyDialogFont(deselectAll);
+		setButtonLayoutData(deselectAll);
+
+		Button refresh = new Button(buttonsComposite, SWT.PUSH);
+		refresh.setText(messsagesLookup.WizardProjectsImportPage_Refresh());
+		refresh.addSelectionListener(new SelectionAdapter() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+			 * .swt.events.SelectionEvent)
+			 */
+			public void widgetSelected(SelectionEvent e) {
+				if (projectFromDirectoryRadio.getSelection()) {
+					updateProjectsList(directoryPathField.getText().trim());
+				} else {
+					updateProjectsList(archivePathField.getText().trim());
+				}
+			}
+		});
+		Dialog.applyDialogFont(refresh);
+		setButtonLayoutData(refresh);
+	}
+
+	/**
+	 * Create the area where you select the root directory for the projects.
+	 * 
+	 * @param workArea
+	 *            Composite
+	 */
+	private void createProjectsRoot(Composite workArea) {
+
+		// project specification group
+		Composite projectGroup = new Composite(workArea, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 3;
+		layout.makeColumnsEqualWidth = false;
+		layout.marginWidth = 0;
+		projectGroup.setLayout(layout);
+		projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		// new project from directory radio button
+		projectFromDirectoryRadio = new Button(projectGroup, SWT.RADIO);
+		projectFromDirectoryRadio.setText(messsagesLookup
+				.WizardProjectsImportPage_RootSelectTitle());
+
+		// project location entry field
+		this.directoryPathField = new Text(projectGroup, SWT.BORDER);
+
+		GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true,
+				false);
+		directoryPathData.widthHint = new PixelConverter(directoryPathField)
+				.convertWidthInCharsToPixels(25);
+		directoryPathField.setLayoutData(directoryPathData);
+
+		// browse button
+		browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);
+		browseDirectoriesButton.setText(messsagesLookup
+				.WizardProjectsImportPage_browse());
+		setButtonLayoutData(browseDirectoriesButton);
+
+		// new project from archive radio button
+		projectFromArchiveRadio = new Button(projectGroup, SWT.RADIO);
+		projectFromArchiveRadio.setText(messsagesLookup
+				.WizardProjectsImportPage_ArchiveSelectTitle());
+
+		// project location entry field
+		archivePathField = new Text(projectGroup, SWT.BORDER);
+
+		GridData archivePathData = new GridData(SWT.FILL, SWT.NONE, true, false);
+		archivePathData.widthHint = new PixelConverter(archivePathField)
+				.convertWidthInCharsToPixels(25);
+		archivePathField.setLayoutData(archivePathData); // browse button
+		browseArchivesButton = new Button(projectGroup, SWT.PUSH);
+		browseArchivesButton.setText(messsagesLookup
+				.WizardProjectsImportPage_browse());
+		setButtonLayoutData(browseArchivesButton);
+
+		projectFromDirectoryRadio.setSelection(true);
+		archivePathField.setEnabled(false);
+		browseArchivesButton.setEnabled(false);
+
+		browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetS
+			 * elected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected(SelectionEvent e) {
+				handleLocationDirectoryButtonPressed();
+			}
+
+		});
+
+		browseArchivesButton.addSelectionListener(new SelectionAdapter() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+			 * .swt.events.SelectionEvent)
+			 */
+			public void widgetSelected(SelectionEvent e) {
+				handleLocationArchiveButtonPressed();
+			}
+
+		});
+
+		directoryPathField.addTraverseListener(new TraverseListener() {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse
+			 * .swt.events.TraverseEvent)
+			 */
+			public void keyTraversed(TraverseEvent e) {
+				if (e.detail == SWT.TRAVERSE_RETURN) {
+					e.doit = false;
+					updateProjectsList(directoryPathField.getText().trim());
+				}
+			}
+
+		});
+
+		directoryPathField.addFocusListener(new FocusAdapter() {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt
+			 * .events.FocusEvent)
+			 */
+			public void focusLost(org.eclipse.swt.events.FocusEvent e) {
+				updateProjectsList(directoryPathField.getText().trim());
+			}
+
+		});
+
+		archivePathField.addTraverseListener(new TraverseListener() {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse
+			 * .swt.events.TraverseEvent)
+			 */
+			public void keyTraversed(TraverseEvent e) {
+				if (e.detail == SWT.TRAVERSE_RETURN) {
+					e.doit = false;
+					updateProjectsList(archivePathField.getText().trim());
+				}
+			}
+
+		});
+
+		archivePathField.addFocusListener(new FocusAdapter() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt
+			 * .events.FocusEvent)
+			 */
+			public void focusLost(org.eclipse.swt.events.FocusEvent e) {
+				updateProjectsList(archivePathField.getText().trim());
+			}
+		});
+
+		projectFromDirectoryRadio.addSelectionListener(new SelectionAdapter() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse
+			 * .swt.events.SelectionEvent)
+			 */
+			public void widgetSelected(SelectionEvent e) {
+				directoryRadioSelected();
+			}
+		});
+
+		projectFromArchiveRadio.addSelectionListener(new SelectionAdapter() {
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse
+			 * .swt.events.SelectionEvent)
+			 */
+			public void widgetSelected(SelectionEvent e) {
+				archiveRadioSelected();
+			}
+		});
+	}
+
+	private void archiveRadioSelected() {
+		if (projectFromArchiveRadio.getSelection()) {
+			directoryPathField.setEnabled(false);
+			browseDirectoriesButton.setEnabled(false);
+			archivePathField.setEnabled(true);
+			browseArchivesButton.setEnabled(true);
+			updateProjectsList(archivePathField.getText());
+			archivePathField.setFocus();
+			copyCheckbox.setSelection(true);
+			copyCheckbox.setEnabled(false);
+		}
+	}
+
+	private void directoryRadioSelected() {
+		if (projectFromDirectoryRadio.getSelection()) {
+			directoryPathField.setEnabled(true);
+			browseDirectoriesButton.setEnabled(true);
+			archivePathField.setEnabled(false);
+			browseArchivesButton.setEnabled(false);
+			updateProjectsList(directoryPathField.getText());
+			directoryPathField.setFocus();
+			copyCheckbox.setEnabled(true);
+			copyCheckbox.setSelection(copyFiles);
+		}
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IDialogPage. Set the focus on path
+	 * fields when page becomes visible.
+	 */
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		if (visible && this.projectFromDirectoryRadio.getSelection()) {
+			this.directoryPathField.setFocus();
+		}
+		if (visible && this.projectFromArchiveRadio.getSelection()) {
+			this.archivePathField.setFocus();
+		}
+	}
+
+	/**
+	 * Update the list of projects based on path. Method declared public only
+	 * for test suite.
+	 * 
+	 * @param path
+	 */
+	public void updateProjectsList(final String path) {
+		// on an empty path empty selectedProjects
+		if (path == null || path.length() == 0) {
+			setMessage(messsagesLookup
+					.WizardProjectsImportPage_ImportProjectsDescription());
+			selectedProjects = new ProjectRecord[0];
+			projectsList.refresh(true);
+			projectsList.setCheckedElements(selectedProjects);
+			setPageComplete(projectsList.getCheckedElements().length > 0);
+			lastPath = path;
+			return;
+		}
+
+		final File directory = new File(path);
+		long modified = directory.lastModified();
+		if (path.equals(lastPath) && lastModified == modified) {
+			// since the file/folder was not modified and the path did not
+			// change, no refreshing is required
+			return;
+		}
+
+		lastPath = path;
+		lastModified = modified;
+
+		// We can't access the radio button from the inner class so get the
+		// status beforehand
+		final boolean dirSelected = this.projectFromDirectoryRadio
+				.getSelection();
+		try {
+			getContainer().run(true, true, new IRunnableWithProgress() {
+
+				/*
+				 * (non-Javadoc)
+				 * 
+				 * @see
+				 * org.eclipse.jface.operation.IRunnableWithProgress#run(org
+				 * .eclipse.core.runtime.IProgressMonitor)
+				 */
+				public void run(IProgressMonitor monitor) {
+
+					monitor.beginTask(messsagesLookup
+							.WizardProjectsImportPage_SearchingMessage(), 100);
+					selectedProjects = new ProjectRecord[0];
+					Collection<Object> files = new ArrayList<Object>();
+					monitor.worked(10);
+					if (!dirSelected
+							&& ArchiveFileManipulations.isTarFile(path,messsagesLookup)) {
+						TarFile sourceTarFile = getSpecifiedTarSourceFile(path);
+						if (sourceTarFile == null) {
+							return;
+						}
+
+						structureProvider = new TarLeveledStructureProvider(
+								sourceTarFile, logger, messsagesLookup);
+						Object child = structureProvider.getRoot();
+
+						if (!collectProjectFilesFromProvider(files, child, 0,
+								monitor)) {
+							return;
+						}
+						Iterator<Object> filesIterator = files.iterator();
+						selectedProjects = new ProjectRecord[files.size()];
+						int index = 0;
+						monitor.worked(50);
+						monitor.subTask(messsagesLookup
+								.WizardProjectsImportPage_ProcessingMessage());
+						while (filesIterator.hasNext()) {
+							selectedProjects[index++] = (ProjectRecord) filesIterator
+									.next();
+						}
+					} else if (!dirSelected
+							&& ArchiveFileManipulations.isZipFile(path)) {
+						ZipFile sourceFile = getSpecifiedZipSourceFile(path);
+						if (sourceFile == null) {
+							return;
+						}
+						structureProvider = new ZipLeveledStructureProvider(
+								sourceFile, logger);
+						Object child = structureProvider.getRoot();
+
+						if (!collectProjectFilesFromProvider(files, child, 0,
+								monitor)) {
+							return;
+						}
+						Iterator<Object> filesIterator = files.iterator();
+						selectedProjects = new ProjectRecord[files.size()];
+						int index = 0;
+						monitor.worked(50);
+						monitor.subTask(messsagesLookup
+								.WizardProjectsImportPage_ProcessingMessage());
+						while (filesIterator.hasNext()) {
+							selectedProjects[index++] = (ProjectRecord) filesIterator
+									.next();
+						}
+					}
+
+					else if (dirSelected && directory.isDirectory()) {
+
+						if (!collectProjectFilesFromDirectory(files, directory,
+								null, monitor)) {
+							return;
+						}
+						Iterator<Object> filesIterator = files.iterator();
+						selectedProjects = new ProjectRecord[files.size()];
+						int index = 0;
+						monitor.worked(50);
+						monitor.subTask(messsagesLookup
+								.WizardProjectsImportPage_ProcessingMessage());
+						while (filesIterator.hasNext()) {
+							File file = (File) filesIterator.next();
+							selectedProjects[index] = new ProjectRecord(file);
+							index++;
+						}
+					} else {
+						monitor.worked(60);
+					}
+					monitor.done();
+				}
+
+			});
+		} catch (InvocationTargetException e) {
+			logger.error(e);
+			// IDEWorkbenchPlugin.log(e.getMessage(), e);
+		} catch (InterruptedException e) {
+			// Nothing to do if the user interrupts.
+		}
+
+		projectsList.refresh(true);
+		ProjectRecord[] projects = getProjectRecords();
+		boolean displayWarning = false;
+		for (int i = 0; i < projects.length; i++) {
+			if (projects[i].hasConflicts) {
+				displayWarning = true;
+				projectsList.setGrayed(projects[i], true);
+			} else {
+				projectsList.setChecked(projects[i], true);
+			}
+		}
+
+		if (displayWarning) {
+			setMessage(
+					messsagesLookup
+							.WizardProjectsImportPage_ProjectsInWorkspace(),
+					WARNING);
+		} else {
+			setMessage(messsagesLookup
+					.WizardProjectsImportPage_ImportProjectsDescription());
+		}
+		setPageComplete(projectsList.getCheckedElements().length > 0);
+		if (selectedProjects.length == 0) {
+			setMessage(
+					messsagesLookup
+							.WizardProjectsImportPage_NoProjectsToImport(),
+					WARNING);
+		}
+	}
+
+	/**
+	 * Answer a handle to the zip file currently specified as being the source.
+	 * Return null if this file does not exist or is not of valid format.
+	 */
+	private ZipFile getSpecifiedZipSourceFile(String fileName) {
+		if (fileName.length() == 0) {
+			return null;
+		}
+
+		try {
+			return new ZipFile(fileName);
+		} catch (ZipException e) {
+			displayErrorDialog(messsagesLookup.ZipImport_badFormat());
+		} catch (IOException e) {
+			displayErrorDialog(messsagesLookup.ZipImport_couldNotRead());
+		}
+
+		archivePathField.setFocus();
+		return null;
+	}
+
+	/**
+	 * Answer a handle to the zip file currently specified as being the source.
+	 * Return null if this file does not exist or is not of valid format.
+	 */
+	private TarFile getSpecifiedTarSourceFile(String fileName) {
+		if (fileName.length() == 0) {
+			return null;
+		}
+
+		try {
+			return new TarFile(fileName,messsagesLookup);
+		} catch (TarException e) {
+			displayErrorDialog(messsagesLookup.TarImport_badFormat());
+		} catch (IOException e) {
+			displayErrorDialog(messsagesLookup.ZipImport_couldNotRead());
+		}
+
+		archivePathField.setFocus();
+		return null;
+	}
+
+	/**
+	 * Display an error dialog with the specified message.
+	 * 
+	 * @param message
+	 *            the error message
+	 */
+	protected void displayErrorDialog(String message) {
+		MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(),
+				getErrorDialogTitle(), message, SWT.SHEET);
+	}
+
+	/**
+	 * Get the title for an error dialog. Subclasses should override.
+	 */
+	protected String getErrorDialogTitle() {
+		return IDEWorkbenchMessages.WizardExportPage_internalErrorTitle;
+	}
+
+	/**
+	 * Collect the list of .project files that are under directory into files.
+	 * 
+	 * @param files
+	 * @param directory
+	 * @param directoriesVisited
+	 *            Set of canonical paths of directories, used as recursion guard
+	 * @param monitor
+	 *            The monitor to report to
+	 * @return boolean <code>true</code> if the operation was completed.
+	 */
+	private boolean collectProjectFilesFromDirectory(Collection<Object> files,
+			File directory, Set<String> directoriesVisited,
+			IProgressMonitor monitor) {
+
+		if (monitor.isCanceled()) {
+			return false;
+		}
+		monitor.subTask(NLS.bind(
+				messsagesLookup.WizardProjectsImportPage_CheckingMessage(),
+				directory.getPath()));
+		File[] contents = directory.listFiles();
+		if (contents == null)
+			return false;
+
+		// Initialize recursion guard for recursive symbolic links
+		if (directoriesVisited == null) {
+			directoriesVisited = new HashSet<String>();
+			try {
+				directoriesVisited.add(directory.getCanonicalPath());
+			} catch (IOException exception) {
+				statusReporter.report(
+						new Status(IStatus.ERROR, FrameworkUtil.getBundle(
+								getClass()).getSymbolicName(), exception
+								.getLocalizedMessage(), exception),
+						StatusReporter.ERROR);
+				// StatusManager.getManager().handle(
+				// StatusUtil.newStatus(IStatus.ERROR, exception
+				// .getLocalizedMessage(), exception));
+			}
+		}
+
+		// first look for project description files
+		final String dotProject = IProjectDescription.DESCRIPTION_FILE_NAME;
+		for (int i = 0; i < contents.length; i++) {
+			File file = contents[i];
+			if (file.isFile() && file.getName().equals(dotProject)) {
+				files.add(file);
+				// don't search sub-directories since we can't have nested
+				// projects
+				return true;
+			}
+		}
+		// no project description found, so recurse into sub-directories
+		for (int i = 0; i < contents.length; i++) {
+			if (contents[i].isDirectory()) {
+				if (!contents[i].getName().equals(METADATA_FOLDER)) {
+					try {
+						String canonicalPath = contents[i].getCanonicalPath();
+						if (!directoriesVisited.add(canonicalPath)) {
+							// already been here --> do not recurse
+							continue;
+						}
+					} catch (IOException exception) {
+						statusReporter.report(
+								new Status(IStatus.ERROR, FrameworkUtil
+										.getBundle(getClass())
+										.getSymbolicName(), exception
+										.getLocalizedMessage(), exception),
+								StatusReporter.ERROR);
+						//
+						// StatusManager.getManager().handle(
+						// StatusUtil.newStatus(IStatus.ERROR, exception
+						// .getLocalizedMessage(), exception));
+
+					}
+					collectProjectFilesFromDirectory(files, contents[i],
+							directoriesVisited, monitor);
+				}
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Collect the list of .project files that are under directory into files.
+	 * 
+	 * @param files
+	 * @param monitor
+	 *            The monitor to report to
+	 * @return boolean <code>true</code> if the operation was completed.
+	 */
+	private boolean collectProjectFilesFromProvider(Collection<Object> files,
+			Object entry, int level, IProgressMonitor monitor) {
+
+		if (monitor.isCanceled()) {
+			return false;
+		}
+		monitor.subTask(NLS.bind(
+				messsagesLookup.WizardProjectsImportPage_CheckingMessage(),
+				structureProvider.getLabel(entry)));
+		List<?> children = structureProvider.getChildren(entry);
+		if (children == null) {
+			children = new ArrayList<Object>(1);
+		}
+		Iterator<?> childrenEnum = children.iterator();
+		while (childrenEnum.hasNext()) {
+			Object child = childrenEnum.next();
+			if (structureProvider.isFolder(child)) {
+				collectProjectFilesFromProvider(files, child, level + 1,
+						monitor);
+			}
+			String elementLabel = structureProvider.getLabel(child);
+			if (elementLabel.equals(IProjectDescription.DESCRIPTION_FILE_NAME)) {
+				files.add(new ProjectRecord(child, entry, level));
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * The browse button has been selected. Select the location.
+	 */
+	protected void handleLocationDirectoryButtonPressed() {
+
+		DirectoryDialog dialog = new DirectoryDialog(
+				directoryPathField.getShell(), SWT.SHEET);
+		dialog.setMessage(messsagesLookup
+				.WizardProjectsImportPage_SelectDialogTitle());
+
+		String dirName = directoryPathField.getText().trim();
+		if (dirName.length() == 0) {
+			dirName = previouslyBrowsedDirectory;
+		}
+
+		if (dirName.length() == 0) {
+			dialog.setFilterPath(workspace.getRoot().getLocation().toOSString());
+		} else {
+			File path = new File(dirName);
+			if (path.exists()) {
+				dialog.setFilterPath(new Path(dirName).toOSString());
+			}
+		}
+
+		String selectedDirectory = dialog.open();
+		if (selectedDirectory != null) {
+			previouslyBrowsedDirectory = selectedDirectory;
+			directoryPathField.setText(previouslyBrowsedDirectory);
+			updateProjectsList(selectedDirectory);
+		}
+
+	}
+
+	/**
+	 * The browse button has been selected. Select the location.
+	 */
+	protected void handleLocationArchiveButtonPressed() {
+
+		FileDialog dialog = new FileDialog(archivePathField.getShell(),
+				SWT.SHEET);
+		dialog.setFilterExtensions(FILE_IMPORT_MASK);
+		dialog.setText(messsagesLookup
+				.WizardProjectsImportPage_SelectArchiveDialogTitle());
+
+		String fileName = archivePathField.getText().trim();
+		if (fileName.length() == 0) {
+			fileName = previouslyBrowsedArchive;
+		}
+
+		if (fileName.length() == 0) {
+			dialog.setFilterPath(workspace.getRoot().getLocation().toOSString());
+		} else {
+			File path = new File(fileName).getParentFile();
+			if (path != null && path.exists()) {
+				dialog.setFilterPath(path.toString());
+			}
+		}
+
+		String selectedArchive = dialog.open();
+		if (selectedArchive != null) {
+			previouslyBrowsedArchive = selectedArchive;
+			archivePathField.setText(previouslyBrowsedArchive);
+			updateProjectsList(selectedArchive);
+		}
+
+	}
+
+	/**
+	 * Create the selected projects
+	 * 
+	 * @return boolean <code>true</code> if all project creations were
+	 *         successful.
+	 */
+	public boolean createProjects() {
+		saveWidgetValues();
+
+		final Object[] selected = projectsList.getCheckedElements();
+		createdProjects = new ArrayList<IProject>();
+		WorkspaceModifyOperation op = new WorkspaceModifyOperation(workspace) {
+
+			protected void execute(IProgressMonitor monitor)
+					throws InvocationTargetException, InterruptedException {
+				try {
+					monitor.beginTask("", selected.length); //$NON-NLS-1$
+					if (monitor.isCanceled()) {
+						throw new OperationCanceledException();
+					}
+					for (int i = 0; i < selected.length; i++) {
+						createExistingProject((ProjectRecord) selected[i],
+								new SubProgressMonitor(monitor, 1));
+					}
+				} finally {
+					monitor.done();
+				}
+			}
+		};
+		// run the new project creation operation
+		try {
+			getContainer().run(true, true, op);
+		} catch (InterruptedException e) {
+			return false;
+		} catch (InvocationTargetException e) {
+			// one of the steps resulted in a core exception
+			Throwable t = e.getTargetException();
+			String message = messsagesLookup
+					.WizardExternalProjectImportPage_ErrorMessage();
+			IStatus status;
+			if (t instanceof CoreException) {
+				status = ((CoreException) t).getStatus();
+			} else {
+				status = new Status(IStatus.ERROR, FrameworkUtil.getBundle(
+						getClass()).getSymbolicName(), 1, message, t);
+			}
+			ErrorDialog.openError(getShell(), message, null, status);
+			return false;
+		}
+		ArchiveFileManipulations.closeStructureProvider(messsagesLookup,
+				structureProvider, getShell());
+
+		// Adds the projects to the working sets
+		// TODO SimpleIDE addToWorkingSets();
+
+		return true;
+	}
+
+	List<IProject> createdProjects;
+
+	// TODO SimpleIDE
+	// private void addToWorkingSets() {
+	//
+	// IWorkingSet[] selectedWorkingSets =
+	// workingSetGroup.getSelectedWorkingSets();
+	// if(selectedWorkingSets == null || selectedWorkingSets.length == 0)
+	// return; // no Working set is selected
+	// IWorkingSetManager workingSetManager =
+	// PlatformUI.getWorkbench().getWorkingSetManager();
+	// for (Iterator i = createdProjects.iterator(); i.hasNext();) {
+	// IProject project = (IProject) i.next();
+	// workingSetManager.addToWorkingSets(project, selectedWorkingSets);
+	// }
+	// }
+
+	/**
+	 * Performs clean-up if the user cancels the wizard without doing anything
+	 */
+	public void performCancel() {
+		ArchiveFileManipulations.closeStructureProvider(messsagesLookup,
+				structureProvider, getShell());
+	}
+
+	/**
+	 * Create the project described in record. If it is successful return true.
+	 * 
+	 * @param record
+	 * @return boolean <code>true</code> if successful
+	 * @throws InterruptedException
+	 */
+	private boolean createExistingProject(final ProjectRecord record,
+			IProgressMonitor monitor) throws InvocationTargetException,
+			InterruptedException {
+		String projectName = record.getProjectName();
+		// final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		final IProject project = workspace.getRoot().getProject(projectName);
+		createdProjects.add(project);
+		if (record.description == null) {
+			// error case
+			record.description = workspace.newProjectDescription(projectName);
+			IPath locationPath = new Path(
+					record.projectSystemFile.getAbsolutePath());
+
+			// If it is under the root use the default location
+			if (Platform.getLocation().isPrefixOf(locationPath)) {
+				record.description.setLocation(null);
+			} else {
+				record.description.setLocation(locationPath);
+			}
+		} else {
+			record.description.setName(projectName);
+		}
+		if (record.projectArchiveFile != null) {
+			// import from archive
+			List<?> fileSystemObjects = structureProvider
+					.getChildren(record.parent);
+			structureProvider.setStrip(record.level);
+			ImportOperation operation = new ImportOperation(workspace,
+					project.getFullPath(), structureProvider.getRoot(),
+					structureProvider, this, fileSystemObjects, messsagesLookup);
+			operation.setContext(getShell());
+			operation.run(monitor);
+			return true;
+		}
+		// import from file system
+		File importSource = null;
+		if (copyFiles) {
+			// import project from location copying files - use default project
+			// location for this workspace
+			URI locationURI = record.description.getLocationURI();
+			// if location is null, project already exists in this location or
+			// some error condition occured.
+			if (locationURI != null) {
+				importSource = new File(locationURI);
+				IProjectDescription desc = workspace
+						.newProjectDescription(projectName);
+				desc.setBuildSpec(record.description.getBuildSpec());
+				desc.setComment(record.description.getComment());
+				desc.setDynamicReferences(record.description
+						.getDynamicReferences());
+				desc.setNatureIds(record.description.getNatureIds());
+				desc.setReferencedProjects(record.description
+						.getReferencedProjects());
+				record.description = desc;
+			}
+		}
+
+		try {
+			monitor.beginTask(messsagesLookup
+					.WizardProjectsImportPage_CreateProjectsTask(), 100);
+			project.create(record.description, new SubProgressMonitor(monitor,
+					30));
+			project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(
+					monitor, 70));
+		} catch (CoreException e) {
+			throw new InvocationTargetException(e);
+		} finally {
+			monitor.done();
+		}
+
+		// import operation to import project files if copy checkbox is selected
+		if (copyFiles && importSource != null) {
+			FileSystemStructureProvider pv = new FileSystemStructureProvider(
+					logger);
+			List<File> filesToImport = pv.getChildren(importSource);
+			ImportOperation operation = new ImportOperation(workspace,
+					project.getFullPath(), importSource, pv, this,
+					filesToImport, messsagesLookup);
+			operation.setContext(getShell());
+			operation.setOverwriteResources(true); // need to overwrite
+			// .project, .classpath
+			// files
+			operation.setCreateContainerStructure(false);
+			operation.run(monitor);
+		}
+
+		return true;
+	}
+
+	/**
+	 * The <code>WizardDataTransfer</code> implementation of this
+	 * <code>IOverwriteQuery</code> method asks the user whether the existing
+	 * resource at the given path should be overwritten.
+	 * 
+	 * @param pathString
+	 * @return the user's reply: one of <code>"YES"</code>, <code>"NO"</code>,
+	 *         <code>"ALL"</code>, or <code>"CANCEL"</code>
+	 */
+	public String queryOverwrite(String pathString) {
+
+		Path path = new Path(pathString);
+
+		String messageString;
+		// Break the message up if there is a file name and a directory
+		// and there are at least 2 segments.
+		if (path.getFileExtension() == null || path.segmentCount() < 2) {
+			messageString = NLS.bind(
+					IDEWorkbenchMessages.WizardDataTransfer_existsQuestion,
+					pathString);
+		} else {
+			messageString = NLS
+					.bind(IDEWorkbenchMessages.WizardDataTransfer_overwriteNameAndPathQuestion,
+							path.lastSegment(), path.removeLastSegments(1)
+									.toOSString());
+		}
+
+		final MessageDialog dialog = new MessageDialog(getContainer()
+				.getShell(), IDEWorkbenchMessages.Question, null,
+				messageString, MessageDialog.QUESTION, new String[] {
+						IDialogConstants.YES_LABEL,
+						IDialogConstants.YES_TO_ALL_LABEL,
+						IDialogConstants.NO_LABEL,
+						IDialogConstants.NO_TO_ALL_LABEL,
+						IDialogConstants.CANCEL_LABEL }, 0) {
+			protected int getShellStyle() {
+				return super.getShellStyle() | SWT.SHEET;
+			}
+		};
+		String[] response = new String[] { YES, ALL, NO, NO_ALL, CANCEL };
+		// run in syncExec because callback is from an operation,
+		// which is probably not running in the UI thread.
+		getControl().getDisplay().syncExec(new Runnable() {
+			public void run() {
+				dialog.open();
+			}
+		});
+		return dialog.getReturnCode() < 0 ? CANCEL : response[dialog
+				.getReturnCode()];
+	}
+
+	/**
+	 * Method used for test suite.
+	 * 
+	 * @return Button the Import from Directory RadioButton
+	 */
+	public Button getProjectFromDirectoryRadio() {
+		return projectFromDirectoryRadio;
+	}
+
+	/**
+	 * Method used for test suite.
+	 * 
+	 * @return CheckboxTreeViewer the viewer containing all the projects found
+	 */
+	public CheckboxTreeViewer getProjectsList() {
+		return projectsList;
+	}
+
+	/**
+	 * Retrieve all the projects in the current workspace.
+	 * 
+	 * @return IProject[] array of IProject in the current workspace
+	 */
+	private IProject[] getProjectsInWorkspace() {
+		if (wsProjects == null) {
+			wsProjects = workspace.getRoot().getProjects();
+		}
+		return wsProjects;
+	}
+
+	/**
+	 * Get the array of project records that can be imported from the source
+	 * workspace or archive, selected by the user. If a project with the same
+	 * name exists in both the source workspace and the current workspace, then
+	 * the hasConflicts flag would be set on that project record.
+	 * 
+	 * Method declared public for test suite.
+	 * 
+	 * @return ProjectRecord[] array of projects that can be imported into the
+	 *         workspace
+	 */
+	public ProjectRecord[] getProjectRecords() {
+		List<ProjectRecord> projectRecords = new ArrayList<ProjectRecord>();
+		for (int i = 0; i < selectedProjects.length; i++) {
+			if (isProjectInWorkspace(selectedProjects[i].getProjectName())) {
+				selectedProjects[i].hasConflicts = true;
+			}
+			projectRecords.add(selectedProjects[i]);
+		}
+		return (ProjectRecord[]) projectRecords
+				.toArray(new ProjectRecord[projectRecords.size()]);
+	}
+
+	/**
+	 * Determine if the project with the given name is in the current workspace.
+	 * 
+	 * @param projectName
+	 *            String the project name to check
+	 * @return boolean true if the project with the given name is in this
+	 *         workspace
+	 */
+	private boolean isProjectInWorkspace(String projectName) {
+		if (projectName == null) {
+			return false;
+		}
+		IProject[] workspaceProjects = getProjectsInWorkspace();
+		for (int i = 0; i < workspaceProjects.length; i++) {
+			if (projectName.equals(workspaceProjects[i].getName())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Use the dialog store to restore widget values to the values that they
+	 * held last time this wizard was used to completion, or alternatively, if
+	 * an initial path is specified, use it to select values.
+	 * 
+	 * Method declared public only for use of tests.
+	 */
+	public void restoreWidgetValues() {
+
+		// First, check to see if we have resore settings, and
+		// take care of the checkbox
+		IDialogSettings settings = getDialogSettings();
+		if (settings != null) {
+			// checkbox
+			copyFiles = settings.getBoolean(STORE_COPY_PROJECT_ID);
+			copyCheckbox.setSelection(copyFiles);
+		}
+
+		// Second, check to see if we don't have an initial path,
+		// and if we do have restore settings. If so, set the
+		// radio selection properly to restore settings
+
+		if (initialPath == null && settings != null) {
+			// radio selection
+			boolean archiveSelected = settings
+					.getBoolean(STORE_ARCHIVE_SELECTED);
+			projectFromDirectoryRadio.setSelection(!archiveSelected);
+			projectFromArchiveRadio.setSelection(archiveSelected);
+			if (archiveSelected) {
+				archiveRadioSelected();
+			} else {
+				directoryRadioSelected();
+			}
+		}
+		// Third, if we do have an initial path, set the proper
+		// path and radio buttons to the initial value. Move
+		// cursor to the end of the path so user can see the
+		// most relevant part (directory / archive name)
+		else if (initialPath != null) {
+			boolean dir = new File(initialPath).isDirectory();
+
+			projectFromDirectoryRadio.setSelection(dir);
+			projectFromArchiveRadio.setSelection(!dir);
+
+			if (dir) {
+				directoryPathField.setText(initialPath);
+				directoryPathField.setSelection(initialPath.length());
+				directoryRadioSelected();
+			} else {
+				archivePathField.setText(initialPath);
+				archivePathField.setSelection(initialPath.length());
+				archiveRadioSelected();
+			}
+		}
+	}
+
+	/**
+	 * Since Finish was pressed, write widget values to the dialog store so that
+	 * they will persist into the next invocation of this wizard page.
+	 * 
+	 * Method declared public only for use of tests.
+	 */
+	public void saveWidgetValues() {
+		IDialogSettings settings = getDialogSettings();
+		if (settings != null) {
+			settings.put(STORE_COPY_PROJECT_ID, copyCheckbox.getSelection());
+
+			settings.put(STORE_ARCHIVE_SELECTED,
+					projectFromArchiveRadio.getSelection());
+		}
+	}
+
+	/**
+	 * Method used for test suite.
+	 * 
+	 * @return Button copy checkbox
+	 */
+	public Button getCopyCheckbox() {
+		return copyCheckbox;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ZipLeveledStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ZipLeveledStructureProvider.java
new file mode 100644
index 0000000..21a0706
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ZipLeveledStructureProvider.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Red Hat, Inc - Was ZipFileStructureProvider, performed changes from 
+ *     IImportStructureProvider to ILeveledImportStructureProvider
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.services.log.Logger;
+
+/**
+ * This class provides information regarding the context structure and content
+ * of specified zip file entry objects.
+ * 
+ * @since 3.1
+ */
+public class ZipLeveledStructureProvider implements
+		ILeveledImportStructureProvider {
+	private ZipFile zipFile;
+
+	private ZipEntry root = new ZipEntry("/");//$NON-NLS-1$
+
+	private Map<ZipEntry,List<ZipEntry>> children;
+
+	private Map<IPath,ZipEntry> directoryEntryCache = new HashMap<IPath,ZipEntry>();
+
+	private int stripLevel;
+	
+	private Logger logger;
+
+	/**
+	 * Creates a <code>ZipFileStructureProvider</code>, which will operate on
+	 * the passed zip file.
+	 * 
+	 * @param sourceFile
+	 *            The source file to create the ZipLeveledStructureProvider
+	 *            around
+	 */
+	public ZipLeveledStructureProvider(ZipFile sourceFile, Logger logger) {
+		super();
+		this.logger = logger;
+		zipFile = sourceFile;
+		stripLevel = 0;
+	}
+
+	/**
+	 * Creates a new container zip entry with the specified name, iff it has 
+	 * not already been created. If the parent of the given element does not
+	 * already exist it will be recursively created as well.
+	 * @param pathname The path representing the container
+	 * @return The element represented by this pathname (it may have already existed)
+	 */
+	protected ZipEntry createContainer(IPath pathname) {
+		ZipEntry existingEntry = (ZipEntry) directoryEntryCache.get(pathname);
+		if (existingEntry != null) {
+			return existingEntry;
+		}
+
+		ZipEntry parent;
+		if (pathname.segmentCount() == 1) {
+			parent = root;
+		} else {
+			parent = createContainer(pathname.removeLastSegments(1));
+		}
+		ZipEntry newEntry = new ZipEntry(pathname.toString());
+		directoryEntryCache.put(pathname, newEntry);
+		List<ZipEntry> childList = new ArrayList<ZipEntry>();
+		children.put(newEntry, childList);
+
+		List<ZipEntry> parentChildList = children.get(parent);
+		parentChildList.add(newEntry);
+		return newEntry;
+	}
+
+	/**
+	 * Creates a new file zip entry with the specified name.
+	 */
+	protected void createFile(ZipEntry entry) {
+		IPath pathname = new Path(entry.getName());
+		ZipEntry parent;
+		if (pathname.segmentCount() == 1) {
+			parent = root;
+		} else {
+			parent = (ZipEntry) directoryEntryCache.get(pathname
+					.removeLastSegments(1));
+		}
+
+		List<ZipEntry> childList = children.get(parent);
+		childList.add(entry);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public List<ZipEntry> getChildren(Object element) {
+		if (children == null) {
+			initialize();
+		}
+
+		return children.get(element);
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public InputStream getContents(Object element) {
+		try {
+			return zipFile.getInputStream((ZipEntry) element);
+		} catch (IOException e) {
+			logger.error(e);
+//			IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+			return null;
+		}
+	}
+
+	/*
+	 * Strip the leading directories from the path
+	 */
+	private String stripPath(String path) {
+		String pathOrig = new String(path);
+		for (int i = 0; i < stripLevel; i++) {
+			int firstSep = path.indexOf('/');
+			// If the first character was a seperator we must strip to the next
+			// seperator as well
+			if (firstSep == 0) {
+				path = path.substring(1);
+				firstSep = path.indexOf('/');
+			}
+			// No seperator wasw present so we're in a higher directory right
+			// now
+			if (firstSep == -1) {
+				return pathOrig;
+			}
+			path = path.substring(firstSep);
+		}
+		return path;
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public String getFullPath(Object element) {
+		return stripPath(((ZipEntry) element).getName());
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public String getLabel(Object element) {
+		if (element.equals(root)) {
+			return ((ZipEntry) element).getName();
+		}
+
+		return stripPath(new Path(((ZipEntry) element).getName()).lastSegment());
+	}
+
+	/**
+	 * Returns the entry that this importer uses as the root sentinel.
+	 * 
+	 * @return java.util.zip.ZipEntry
+	 */
+	public Object getRoot() {
+		return root;
+	}
+
+	/**
+	 * Returns the zip file that this provider provides structure for.
+	 * 
+	 * @return The zip file
+	 */
+	public ZipFile getZipFile() {
+		return zipFile;
+	}
+
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider#closeArchive()
+	 */
+	public boolean closeArchive(){
+		try {
+			getZipFile().close();
+		} catch (IOException e) {
+			logger.error(e);
+//			IDEWorkbenchPlugin.log(DataTransferMessages.ZipImport_couldNotClose
+//					+ getZipFile().getName(), e);
+			return false;
+		}
+		return true;
+	}
+	
+	/**
+	 * Initializes this object's children table based on the contents of the
+	 * specified source file.
+	 */
+	protected void initialize() {
+		children = new HashMap<ZipEntry,List<ZipEntry>>(1000);
+
+		children.put(root, new ArrayList<ZipEntry>());
+		Enumeration<?> entries = zipFile.entries();
+		while (entries.hasMoreElements()) {
+			ZipEntry entry = (ZipEntry) entries.nextElement();
+			IPath path = new Path(entry.getName()).addTrailingSeparator();
+
+			if (entry.isDirectory()) {
+				createContainer(path);
+			} else
+			{
+				// Ensure the container structure for all levels above this is initialized
+				// Once we hit a higher-level container that's already added we need go no further
+				int pathSegmentCount = path.segmentCount();
+				if (pathSegmentCount > 1) {
+					createContainer(path.uptoSegment(pathSegmentCount - 1));
+				}
+				createFile(entry);
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IImportStructureProvider
+	 */
+	public boolean isFolder(Object element) {
+		return ((ZipEntry) element).isDirectory();
+	}
+
+	public void setStrip(int level) {
+		stripLevel = level;
+	}
+
+	public int getStrip() {
+		return stripLevel;
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/actions/WorkspaceModifyOperation.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/actions/WorkspaceModifyOperation.java
new file mode 100644
index 0000000..9dbc19c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/actions/WorkspaceModifyOperation.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.IThreadListener;
+
+//import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * An operation which potentially makes changes to the workspace. All resource
+ * modification should be performed using this operation. The primary
+ * consequence of using this operation is that events which typically occur as a
+ * result of workspace changes (such as the firing of resource deltas,
+ * performance of autobuilds, etc.) are generally deferred until the outermost operation
+ * has successfully completed.  The platform may still decide to broadcast
+ * periodic resource change notifications during the scope of the operation
+ * if the operation runs for a long time or another thread modifies the workspace
+ * concurrently.
+ * <p>
+ * If a scheduling rule is provided, the operation will obtain that scheduling
+ * rule for the duration of its <code>execute</code> method.  If no scheduling
+ * rule is provided, the operation will obtain a scheduling rule that locks
+ * the entire workspace for the duration of the operation.
+ * </p>
+ * <p>
+ * Subclasses must implement <code>execute</code> to do the work of the
+ * operation.
+ * </p>
+ * @see ISchedulingRule
+ * @see org.eclipse.core.resources.IWorkspace#run(IWorkspaceRunnable, IProgressMonitor)
+ *  */
+public abstract class WorkspaceModifyOperation implements IRunnableWithProgress, IThreadListener {
+    private ISchedulingRule rule;
+    private IWorkspace workspace;
+
+    /**
+     * Creates a new operation.
+     */
+    protected WorkspaceModifyOperation(IWorkspace workspace) {
+        this(workspace, workspace.getRoot());
+    }
+
+    /**
+     * Creates a new operation that will run using the provided
+     * scheduling rule.
+     * @param rule  The ISchedulingRule to use or <code>null</code>.
+     * @since 3.0
+     */
+    protected WorkspaceModifyOperation(IWorkspace workspace, ISchedulingRule rule) {
+    	this.workspace = workspace;
+        this.rule = rule;
+    }
+
+    /**
+     * Performs the steps that are to be treated as a single logical workspace
+     * change.
+     * <p>
+     * Subclasses must implement this method.
+     * </p>
+     *
+     * @param monitor the progress monitor to use to display progress and field
+     *   user requests to cancel
+     * @exception CoreException if the operation fails due to a CoreException
+     * @exception InvocationTargetException if the operation fails due to an exception other than CoreException
+     * @exception InterruptedException if the operation detects a request to cancel,
+     *  using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing
+     *  <code>InterruptedException</code>.  It is also possible to throw
+     *  <code>OperationCanceledException</code>, which gets mapped to <code>InterruptedException</code>
+     *  by the <code>run</code> method.
+     */
+    protected abstract void execute(IProgressMonitor monitor)
+            throws CoreException, InvocationTargetException,
+            InterruptedException;
+
+    /**
+     * The <code>WorkspaceModifyOperation</code> implementation of this
+     * <code>IRunnableWithProgress</code> method initiates a batch of changes by
+     * invoking the <code>execute</code> method as a workspace runnable
+     * (<code>IWorkspaceRunnable</code>).
+     */
+    public synchronized final void run(IProgressMonitor monitor)
+            throws InvocationTargetException, InterruptedException {
+        final InvocationTargetException[] iteHolder = new InvocationTargetException[1];
+        try {
+            IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {
+                public void run(IProgressMonitor pm) throws CoreException {
+                    try {
+                        execute(pm);
+                    } catch (InvocationTargetException e) {
+                        // Pass it outside the workspace runnable
+                        iteHolder[0] = e;
+                    } catch (InterruptedException e) {
+                        // Re-throw as OperationCanceledException, which will be
+                        // caught and re-thrown as InterruptedException below.
+                        throw new OperationCanceledException(e.getMessage());
+                    }
+                    // CoreException and OperationCanceledException are propagated
+                }
+            };
+            workspace.run(workspaceRunnable,
+                    rule, IResource.NONE, monitor);
+        } catch (CoreException e) {
+            throw new InvocationTargetException(e);
+        } catch (OperationCanceledException e) {
+            throw new InterruptedException(e.getMessage());
+        }
+        // Re-throw the InvocationTargetException, if any occurred
+        if (iteHolder[0] != null) {
+            throw iteHolder[0];
+        }
+    }
+	/* (non-Javadoc)
+	 * @see IThreadListener#threadChange(Thread);
+	 * @since 3.2
+	 */
+	public void threadChange(Thread thread) {
+		//we must make sure we aren't transferring control away from a thread that
+		//already owns a scheduling rule because this is deadlock prone (bug 105491)
+		if (rule == null) {
+			return;
+		}
+		Job currentJob = Job.getJobManager().currentJob();
+		if (currentJob == null) {
+			return;
+		}
+		ISchedulingRule currentRule = currentJob.getRule();
+		if (currentRule == null) {
+			return;
+		}
+		throw new IllegalStateException("Cannot fork a thread from a thread owning a rule"); //$NON-NLS-1$
+	}
+
+	/**
+	 * The scheduling rule.  Should not be modified.
+	 * @return the scheduling rule, or <code>null</code>.
+	 * @since 3.4
+	 */
+	public ISchedulingRule getRule() {
+		return rule;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/ContainerGenerator.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/ContainerGenerator.java
new file mode 100644
index 0000000..bd3319d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/ContainerGenerator.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.IDEWorkbenchMessages;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * For creating folder resources that currently do not exist, 
+ * along a given workspace path.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example usage:
+ * <pre>
+ * ContainerGenerator gen = new ContainerGenerator(new Path("/A/B"));
+ * IContainer res = null;
+ * try {
+ *   res = gen.getContainer(monitor); // creates project A and folder B if required
+ * } catch (CoreException e) {
+ *   // handle failure
+ * } catch (OperationCanceledException e) {
+ *   // handle cancelation
+ * }
+ * </pre>
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ContainerGenerator {
+    private IPath containerFullPath;
+
+    private IContainer container;
+    
+    private IWorkspace workspace;
+
+    /**
+     * Creates a generator for the container resource (folder or project) at the
+     * given workspace path. Assumes the path has already been validated.
+     * <p>
+     * Call <code>getContainer</code> to create any missing resources along the
+     * path.
+     * </p>
+     *
+     * @param containerPath the workspace path of the container
+     */
+    public ContainerGenerator(IWorkspace workspace, IPath containerPath) {
+        super();
+        this.workspace = workspace;
+        this.containerFullPath = containerPath;
+    }
+
+    /**
+     * Creates a folder resource for the given folder handle.
+     *
+     * @param folderHandle the handle to create a folder resource
+     * @param monitor the progress monitor to show visual progress
+     * @return the folder handle (<code>folderHandle</code>)
+     * @exception CoreException if the operation fails
+     * @exception OperationCanceledException if the operation is canceled
+     */
+    private IFolder createFolder(IFolder folderHandle, IProgressMonitor monitor)
+            throws CoreException {
+        folderHandle.create(false, true, monitor);
+
+        if (monitor.isCanceled()) {
+			throw new OperationCanceledException();
+		}
+
+        return folderHandle;
+    }
+
+    /**
+     * Creates a folder resource handle for the folder with the given name.
+     * This method does not create the folder resource; this is the responsibility
+     * of <code>createFolder</code>.
+     *
+     * @param container the resource container
+     * @param folderName the name of the folder
+     * @return the new folder resource handle
+     */
+    private IFolder createFolderHandle(IContainer container, String folderName) {
+        return container.getFolder(new Path(folderName));
+    }
+
+    /**
+     * Creates a project resource for the given project handle.
+     *
+     * @param projectHandle the handle to create a project resource
+     * @param monitor the progress monitor to show visual progress
+     * @return the project handle (<code>projectHandle</code>)
+     * @exception CoreException if the operation fails
+     * @exception OperationCanceledException if the operation is canceled
+     */
+    private IProject createProject(IProject projectHandle,
+            IProgressMonitor monitor) throws CoreException {
+        try {
+            monitor.beginTask("", 2000);//$NON-NLS-1$
+
+            projectHandle.create(new SubProgressMonitor(monitor, 1000));
+            if (monitor.isCanceled()) {
+				throw new OperationCanceledException();
+			}
+
+            projectHandle.open(new SubProgressMonitor(monitor, 1000));
+            if (monitor.isCanceled()) {
+				throw new OperationCanceledException();
+			}
+        } finally {
+            monitor.done();
+        }
+
+        return projectHandle;
+    }
+
+    /**
+     * Creates a project resource handle for the project with the given name.
+     * This method does not create the project resource; this is the responsibility
+     * of <code>createProject</code>.
+     *
+     * @param root the workspace root resource
+     * @param projectName the name of the project
+     * @return the new project resource handle
+     */
+    private IProject createProjectHandle(IWorkspaceRoot root, String projectName) {
+        return root.getProject(projectName);
+    }
+
+    /**
+     * Ensures that this generator's container resource exists. Creates any missing
+     * resource containers along the path; does nothing if the container resource
+     * already exists.
+     * <p>
+     * Note: This method should be called within a workspace modify operation since
+     * it may create resources.
+     * </p>
+     *
+     * @param monitor a progress monitor
+     * @return the container resource
+     * @exception CoreException if the operation fails
+     * @exception OperationCanceledException if the operation is canceled
+     */
+    public IContainer generateContainer(IProgressMonitor monitor)
+            throws CoreException {
+        workspace.run(new IWorkspaceRunnable() {
+            public void run(IProgressMonitor monitor) throws CoreException {
+                monitor
+                        .beginTask(
+                                IDEWorkbenchMessages.ContainerGenerator_progressMessage, 1000 * containerFullPath.segmentCount());
+                if (container != null) {
+					return;
+				}
+
+                // Does the container exist already?
+                IWorkspaceRoot root = getWorkspaceRoot();
+                container = (IContainer) root.findMember(containerFullPath);
+                if (container != null) {
+					return;
+				}
+
+                // Create the container for the given path
+                container = root;
+                for (int i = 0; i < containerFullPath.segmentCount(); i++) {
+                    String currentSegment = containerFullPath.segment(i);
+                    IResource resource = container.findMember(currentSegment);
+                    if (resource != null) {
+                    	if (resource.getType() == IResource.FILE) {
+                    		String msg = NLS.bind(IDEWorkbenchMessages.ContainerGenerator_pathOccupied, resource.getFullPath().makeRelative());
+                    		throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(), 1, msg, null));
+                    	}
+                        container = (IContainer) resource;
+                        monitor.worked(1000);
+                    } else {
+                        if (i == 0) {
+                            IProject projectHandle = createProjectHandle(root,
+                                    currentSegment);
+                            container = createProject(projectHandle,
+                                    new SubProgressMonitor(monitor, 1000));
+                        } else {
+                            IFolder folderHandle = createFolderHandle(
+                                    container, currentSegment);
+                            container = createFolder(folderHandle,
+                                    new SubProgressMonitor(monitor, 1000));
+                        }
+                    }
+                }
+            }
+        }, null, IResource.NONE, monitor);
+        return container;
+    }
+
+    /**
+     * Returns the workspace root resource handle.
+     *
+     * @return the workspace root resource handle
+     */
+    private IWorkspaceRoot getWorkspaceRoot() {
+        return workspace.getRoot();
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/IOverwriteQuery.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/IOverwriteQuery.java
new file mode 100644
index 0000000..7c72b77
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/IOverwriteQuery.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs;
+
+/**
+ *	Implementors of this interface answer one of the prescribed return codes
+ *	when asked whether to overwrite a certain path string (which could
+ *	represent a resource path, a file system path, etc).
+ */
+public interface IOverwriteQuery {
+    /**
+     * Return code indicating the operation should be canceled.
+     */
+    public static final String CANCEL = "CANCEL"; //$NON-NLS-1$
+
+    /**
+     * Return code indicating the entity should not be overwritten, 
+     * but operation should not be canceled.
+     */
+    public static final String NO = "NO"; //$NON-NLS-1$
+
+    /**
+     * Return code indicating the entity should be overwritten.
+     */
+    public static final String YES = "YES"; //$NON-NLS-1$
+
+    /**
+     * Return code indicating the entity should be overwritten, 
+     * and all subsequent entities should be overwritten without prompting.
+     */
+    public static final String ALL = "ALL"; //$NON-NLS-1$
+
+    /**
+     * Return code indicating the entity should not be overwritten, 
+     * and all subsequent entities should not be overwritten without prompting.
+     */
+    public static final String NO_ALL = "NOALL"; //$NON-NLS-1$
+
+    /**
+     * Returns one of the return code constants declared on this interface,
+     * indicating whether the entity represented by the passed String should be overwritten.
+     * <p>
+     * This method may be called from a non-UI thread, in which case this method must run the query
+     * in a sync exec in the UI thread, if it needs to query the user.
+     * </p>
+     * @param pathString the path representing the entity to be overwritten
+     * @return one of the return code constants declared on this interface
+     */
+    String queryOverwrite(String pathString);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/ui/ResourceViewerControl.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/ui/ResourceViewerControl.java
new file mode 100644
index 0000000..c0c455c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/ui/ResourceViewerControl.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.ui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class ResourceViewerControl extends Composite {
+	private TreeViewer viewer;
+	
+	public ResourceViewerControl(Composite parent, int style, IWorkspace workspace, IResource resource) {
+		super(parent, style);
+		setLayout(new FillLayout());
+				
+		viewer = new TreeViewer(this);
+		viewer.setContentProvider(new ResourceContentProviderImpl());
+		viewer.setLabelProvider(new LabelProvider() {
+			public String getText(Object element) {
+				if (element instanceof IResource)
+					return ((IResource) element).getName();
+				return element == null ? "" : element.toString();
+			}
+		});
+		viewer.setSorter(new ViewerSorter());
+		viewer.setInput(workspace.getRoot());
+		
+		if( resource != null ) {
+			IContainer resContainer;
+			if( resource instanceof IContainer ) {
+				resContainer = (IContainer) resource;
+			} else {
+				resContainer = resource.getParent();
+			}
+			
+			if( resContainer != null ) {
+				List<IContainer> path = new ArrayList<IContainer>();
+				path.add(resContainer);
+				while( (resContainer = resContainer.getParent()) != null ) {
+					path.add(resContainer);
+				}
+				Collections.reverse(path);
+				path.remove(0);
+				viewer.setSelection(new TreeSelection(new TreePath(path.toArray())));
+			}
+		}
+	}
+
+	public IResource getResource() {
+		if( viewer.getSelection().isEmpty() ) {
+			return null;
+		} else {
+			IStructuredSelection s = (IStructuredSelection) viewer.getSelection();
+			return (IResource) s.getFirstElement();
+		}
+	}
+	
+	private static class ResourceContentProviderImpl implements ITreeContentProvider {
+
+		public Object[] getElements(Object inputElement) {
+			return getChildren(inputElement);
+		}
+
+		public void dispose() {
+			// TODO Auto-generated method stub
+			
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			// TODO Auto-generated method stub
+			
+		}
+
+		public Object[] getChildren(Object parentElement) {
+			final IContainer resource = (IContainer) parentElement;
+			final List<IResource> children = new ArrayList<IResource>();
+			try {
+				for( IResource res : resource.members() ) {
+					if( res instanceof IContainer ) {
+						children.add(res);
+					}
+				}
+			} catch (CoreException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return children.toArray();
+		}
+
+		public Object getParent(Object element) {
+			IContainer resource = (IContainer) element;
+			return resource.getParent();
+		}
+
+		public boolean hasChildren(Object element) {
+			return getChildren(element).length > 0;
+		}
+		
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.classpath b/examples/org.eclipse.e4.demo.tools.simpleide/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.project b/examples/org.eclipse.e4.demo.tools.simpleide/.project
new file mode 100644
index 0000000..f721119
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.tools.simpleide</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9ef8794
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat May 15 11:15:26 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..360454f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Wed Jun 02 15:50:17 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.tools.simpleide/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5e524dd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simpleide
+Bundle-SymbolicName: org.eclipse.e4.demo.tools.simpleide;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.tools.emf.ui;bundle-version="0.9.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ javax.inject;bundle-version="1.0.0",
+ org.eclipse.emf.ecore;bundle-version="2.6.0",
+ org.eclipse.emf.databinding;bundle-version="1.2.0",
+ org.eclipse.core.databinding.property;bundle-version="1.3.0",
+ org.eclipse.emf.databinding.edit;bundle-version="1.2.0",
+ org.eclipse.jface.databinding;bundle-version="1.4.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.tools.services;bundle-version="0.11.0"
+Import-Package: org.eclipse.core.databinding.observable.list,
+ org.eclipse.core.resources,
+ org.eclipse.emf.edit.domain
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/build.properties b/examples/org.eclipse.e4.demo.tools.simpleide/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/plugin.xml b/examples/org.eclipse.e4.demo.tools.simpleide/plugin.xml
new file mode 100644
index 0000000..9426186
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.e4.tools.emf.ui.editors">
+      <editor
+            descriptorClass="org.eclipse.e4.demo.tools.simpleide.SimpleIDEApplicationEditorDesc">
+      </editor>
+      <virtualeditor
+            class="org.eclipse.e4.demo.tools.simpleide.VEditorPartDescriptorEditor"
+            id="org.eclipse.e4.demo.tools.simpleide.SimpleIDEApplicationEditor.EDITOR_DESCRIPTORS">
+      </virtualeditor>
+      <editor
+            descriptorClass="org.eclipse.e4.demo.tools.simpleide.EditorPartDescriptorEditorDesc">
+      </editor>
+      <editorfeature
+            class="org.eclipse.e4.demo.tools.simpleide.EditorFeature">
+      </editorfeature>
+   </extension>
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorFeature.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorFeature.java
new file mode 100644
index 0000000..f8e5cad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorFeature.java
@@ -0,0 +1,23 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IEditorFeature;
+import org.eclipse.e4.ui.model.fragment.impl.FragmentPackageImpl;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class EditorFeature implements IEditorFeature {
+
+	public List<FeatureClass> getFeatureClasses(EClass eClass,
+			EStructuralFeature feature) {
+		if( eClass == FragmentPackageImpl.Literals.MODEL_FRAGMENT ) {
+			if( feature == FragmentPackageImpl.Literals.MODEL_FRAGMENT__ELEMENTS ) {
+				return Collections.singletonList(new FeatureClass(SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR.getName(), SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR));
+			}
+		}
+		return Collections.emptyList();
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditor.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditor.java
new file mode 100644
index 0000000..786955f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditor.java
@@ -0,0 +1,174 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.core.di.annotations.Optional;
+
+import org.eclipse.e4.tools.emf.ui.internal.Messages;
+
+import javax.inject.Inject;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
+import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.ControlFactory;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.ContributionClassDialog;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
+import org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.databinding.EMFDataBindingContext;
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
+import org.eclipse.jface.databinding.swt.IWidgetValueProperty;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class EditorPartDescriptorEditor extends AbstractComponentEditor {
+	private Composite composite;
+	private EMFDataBindingContext context;
+	
+	@Inject
+	@Optional
+	private IProject project;
+	
+	@Inject
+	public EditorPartDescriptorEditor() {
+		super();
+	}
+
+	@Override
+	public Image getImage(Object element, Display display) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String getLabel(Object element) {
+		return "Editor Descriptor";
+	}
+
+	@Override
+	public String getDetailLabel(Object element) {
+		MEditorPartDescriptor desc = (MEditorPartDescriptor) element;
+		return desc.getLabel();
+	}
+
+	@Override
+	public String getDescription(Object element) {
+		return "Editor Descriptor Bla Bla Bla Bla Bla";
+	}
+
+	@Override
+	public Composite doGetEditor(Composite parent, Object object) {
+		if( composite == null ) {
+			context = new EMFDataBindingContext();
+			composite = createForm(parent,context, getMaster());
+		}
+		getMaster().setValue(object);
+		return composite;
+	}
+	
+	protected Composite createForm(Composite parent, EMFDataBindingContext context, IObservableValue master) {
+		parent = new Composite(parent,SWT.NONE);
+		parent.setLayout(new GridLayout(3, false));
+
+		IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify);
+
+		// ------------------------------------------------------------
+		{
+			Label l = new Label(parent, SWT.NONE);
+			l.setText("Id");
+
+			Text t = new Text(parent, SWT.BORDER);
+			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+			gd.horizontalSpan=2;
+			t.setLayoutData(gd);
+			context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__ELEMENT_ID).observeDetail(master));			
+		}
+
+		// ------------------------------------------------------------
+		{
+			Label l = new Label(parent, SWT.NONE);
+			l.setText("Label");
+
+			Text t = new Text(parent, SWT.BORDER);
+			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+			gd.horizontalSpan=2;
+			t.setLayoutData(gd);
+			context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__LABEL).observeDetail(master));			
+		}
+		
+		// ------------------------------------------------------------
+		{
+			Label l = new Label(parent, SWT.NONE);
+			l.setText("Tooltip");
+
+			Text t = new Text(parent, SWT.BORDER);
+			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+			gd.horizontalSpan=2;
+			t.setLayoutData(gd);
+			context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__TOOLTIP).observeDetail(master));			
+		}
+
+		// ------------------------------------------------------------
+		{
+			Label l = new Label(parent, SWT.NONE);
+			l.setText("Icon URI");
+
+			Text t = new Text(parent, SWT.BORDER);
+			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__ICON_URI).observeDetail(master));
+
+			Button b = new Button(parent, SWT.PUSH|SWT.FLAT);
+			b.setImage(createImage(ResourceProvider.IMG_Obj16_zoom));
+			b.setText("Find");			
+		}
+		
+		// ------------------------------------------------------------
+		{
+			Label l = new Label(parent, SWT.NONE);
+			l.setText("Class URI");
+
+			Text t = new Text(parent, SWT.BORDER);
+			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI).observeDetail(master));
+
+			final Button b = new Button(parent, SWT.PUSH|SWT.FLAT);
+			b.setImage(createImage(ResourceProvider.IMG_Obj16_zoom));
+			b.setText("Find");
+			b.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					ContributionClassDialog dialog = new ContributionClassDialog(b.getShell(),project,getEditingDomain(),(MPartDescriptor) getMaster().getValue(), BasicPackageImpl.Literals.PART_DESCRIPTOR__CONTRIBUTION_URI, Messages);
+					dialog.open();
+				}
+			});
+		}
+
+
+		// ------------------------------------------------------------
+		{
+			ControlFactory.createStringListWidget(parent, Messages, this, "File extensions", SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS, 10);
+		}
+		
+		return parent;
+	}
+
+	@Override
+	public IObservableList getChildList(Object element) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditorDesc.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditorDesc.java
new file mode 100644
index 0000000..c9e719f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditorDesc.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IEditorDescriptor;
+import org.eclipse.emf.ecore.EClass;
+
+public class EditorPartDescriptorEditorDesc implements IEditorDescriptor {
+
+	public EClass getEClass() {
+		return SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR;
+	}
+
+	public Class<?> getEditorClass() {
+		return EditorPartDescriptorEditor.class;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditor.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditor.java
new file mode 100644
index 0000000..d95be15
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditor.java
@@ -0,0 +1,45 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.tools.services.IResourcePool;
+
+import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
+
+import javax.inject.Inject;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.property.list.IListProperty;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IModelResource;
+import org.eclipse.e4.tools.emf.ui.internal.common.VirtualEntry;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.ApplicationEditor;
+import org.eclipse.emf.databinding.EMFProperties;
+
+@SuppressWarnings({ "restriction"})
+public class SimpleIDEApplicationEditor extends ApplicationEditor {
+	private static final String EDITOR_DESCRIPTORS_ID = SimpleIDEApplicationEditor.class.getName() + ".EDITOR_DESCRIPTORS"; 
+	private IListProperty EDITOR_DESCRIPTORS = EMFProperties.list(SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS);
+	
+	
+	@Inject
+	public SimpleIDEApplicationEditor() {
+		super();
+	}
+	
+	@Override
+	public String getLabel(Object element) {
+		return "SimpleIDE Application";
+	}
+	
+	@Override
+	public IObservableList getChildList(Object element) {
+		IObservableList list = super.getChildList(element);
+		VirtualEntry<Object> v = new VirtualEntry<Object>(EDITOR_DESCRIPTORS_ID,EDITOR_DESCRIPTORS,element,"Editor Part Descriptors") {
+
+			@Override
+			protected boolean accepted(Object o) {
+				return true;
+			}
+		};
+		list.add(v);
+		return list;
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditorDesc.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditorDesc.java
new file mode 100644
index 0000000..e1f2b1c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditorDesc.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IEditorDescriptor;
+import org.eclipse.emf.ecore.EClass;
+
+public class SimpleIDEApplicationEditorDesc implements IEditorDescriptor {
+
+	public EClass getEClass() {
+		return SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION;
+	}
+
+	public Class<?> getEditorClass() {
+		return SimpleIDEApplicationEditor.class;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/VEditorPartDescriptorEditor.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/VEditorPartDescriptorEditor.java
new file mode 100644
index 0000000..05302b9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/VEditorPartDescriptorEditor.java
@@ -0,0 +1,223 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.tools.services.IResourcePool;
+
+import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
+
+import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
+
+import java.util.List;
+import javax.inject.Inject;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.WritableValue;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IModelResource;
+import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
+import org.eclipse.e4.tools.emf.ui.internal.ObservableColumnLabelProvider;
+import org.eclipse.e4.tools.emf.ui.internal.common.VirtualEntry;
+import org.eclipse.e4.ui.model.application.commands.MHandler;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.databinding.EMFDataBindingContext;
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
+import org.eclipse.emf.databinding.edit.IEMFEditValueProperty;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.MoveCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+public class VEditorPartDescriptorEditor extends AbstractComponentEditor {
+	private Composite composite;
+	private EMFDataBindingContext context;
+	private TableViewer viewer;
+	
+	@Inject
+	public VEditorPartDescriptorEditor() {
+		super();
+	}
+
+	@Override
+	public Image getImage(Object element, Display display) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String getLabel(Object element) {
+		return "Editor Part Descriptors";
+	}
+
+	@Override
+	public String getDetailLabel(Object element) {
+		return null;
+	}
+
+	@Override
+	public String getDescription(Object element) {
+		return "Editor Part Descriptors Bla Bla Bla Bla";
+	}
+
+	@Override
+	public Composite doGetEditor(Composite parent, Object object) {
+		if( composite == null ) {
+			context = new EMFDataBindingContext();
+			composite = createForm(parent,context, getMaster());
+		}
+		VirtualEntry<?> o = (VirtualEntry<?>)object;
+		viewer.setInput(o.getList());
+		getMaster().setValue(o.getOriginalParent());
+		return composite;
+	}
+
+	private Composite createForm(Composite parent, EMFDataBindingContext context,
+			WritableValue master) {
+		parent = new Composite(parent,SWT.NONE);
+		parent.setLayout(new GridLayout(3, false));
+
+		{
+			Label l = new Label(parent, SWT.NONE);
+			l.setText("Descriptors");
+			l.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+
+			viewer = new TableViewer(parent);
+			ObservableListContentProvider cp = new ObservableListContentProvider();
+			viewer.setContentProvider(cp);
+			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+			gd.heightHint = 300;
+			viewer.getControl().setLayoutData(gd);
+			viewer.getTable().setHeaderVisible(true);
+
+			{
+				IEMFEditValueProperty prop = EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__LABEL);
+					
+				TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
+				column.getColumn().setText("Name");
+				column.getColumn().setWidth(200);
+				column.setLabelProvider(new ObservableColumnLabelProvider<MHandler>(prop.observeDetail(cp.getKnownElements())));
+			}
+									
+			Composite buttonComp = new Composite(parent, SWT.NONE);
+			buttonComp.setLayoutData(new GridData(GridData.FILL,GridData.END,false,false));
+			GridLayout gl = new GridLayout();
+			gl.marginLeft=0;
+			gl.marginRight=0;
+			gl.marginWidth=0;
+			gl.marginHeight=0;
+			buttonComp.setLayout(gl);
+
+			Button b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+			b.setText("Up");
+			b.setImage(createImage(ResourceProvider.IMG_Obj16_arrow_up));
+			b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+			b.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					if( ! viewer.getSelection().isEmpty() ) {
+						IStructuredSelection s = (IStructuredSelection)viewer.getSelection();
+						if( s.size() == 1 ) {
+							Object obj = s.getFirstElement();
+							MPartDescriptorContainer container = (MPartDescriptorContainer) getMaster().getValue();
+							int idx = container.getDescriptors().indexOf(obj) - 1;
+							if( idx >= 0 ) {
+								Command cmd = MoveCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, obj, idx);
+								
+								if( cmd.canExecute() ) {
+									getEditingDomain().getCommandStack().execute(cmd);
+									viewer.setSelection(new StructuredSelection(obj));
+								}
+							}
+							
+						}
+					}
+				}
+			});
+
+			b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+			b.setText("Down");
+			b.setImage(createImage(ResourceProvider.IMG_Obj16_arrow_down));
+			b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+			b.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					if( ! viewer.getSelection().isEmpty() ) {
+						IStructuredSelection s = (IStructuredSelection)viewer.getSelection();
+						if( s.size() == 1 ) {
+							Object obj = s.getFirstElement();
+							MPartDescriptorContainer container = (MPartDescriptorContainer) getMaster().getValue();
+							int idx = container.getDescriptors().indexOf(obj) + 1;
+							if( idx < container.getDescriptors().size() ) {
+								Command cmd = MoveCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, obj, idx);
+								
+								if( cmd.canExecute() ) {
+									getEditingDomain().getCommandStack().execute(cmd);
+									viewer.setSelection(new StructuredSelection(obj));
+								}
+							}
+							
+						}
+					}
+				}
+			});
+
+			b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+			b.setText("Add ...");
+			b.setImage(createImage(ResourceProvider.IMG_Obj16_table_add));
+			b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+			b.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					MEditorPartDescriptor obj = MSimpleideFactory.INSTANCE.createEditorPartDescriptor();
+					Command cmd = AddCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, obj);
+					
+					if( cmd.canExecute() ) {
+						getEditingDomain().getCommandStack().execute(cmd);
+//TODO Need to abstract this	editor.setSelection(command);
+					}
+				}
+			});
+
+			b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+			b.setText("Remove");
+			b.setImage(createImage(ResourceProvider.IMG_Obj16_table_delete));
+			b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+			b.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					if( ! viewer.getSelection().isEmpty() ) {
+						List<?> commands = ((IStructuredSelection)viewer.getSelection()).toList();
+						Command cmd = RemoveCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, commands);
+						if( cmd.canExecute() ) {
+							getEditingDomain().getCommandStack().execute(cmd);
+						}
+					}
+				}
+			});
+		}
+
+		return parent;
+	}
+
+	@Override
+	public IObservableList getChildList(Object element) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/.classpath b/examples/org.eclipse.e4.demo.tools.simpleide3x/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/.project b/examples/org.eclipse.e4.demo.tools.simpleide3x/.project
new file mode 100644
index 0000000..3d69bf1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.tools.simpleide3x</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.tools.simpleide3x/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..5699a5c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat May 15 13:45:29 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.tools.simpleide3x/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e5cb063
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simpleide3x
+Bundle-SymbolicName: org.eclipse.e4.demo.tools.simpleide3x;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.tools.emf.editor3x;bundle-version="0.9.0",
+ org.eclipse.emf.ecore;bundle-version="2.6.0",
+ org.eclipse.ui;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.tools;bundle-version="0.9.0"
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/build.properties b/examples/org.eclipse.e4.demo.tools.simpleide3x/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/plugin.xml b/examples/org.eclipse.e4.demo.tools.simpleide3x/plugin.xml
new file mode 100644
index 0000000..aeea30c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/plugin.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.newWizards">
+      <wizard
+            canFinishEarly="false"
+            category="org.eclipse.e4.tools/org.eclipse.e4.tools.model"
+            class="org.eclipse.e4.demo.tools.simpleide3x.SimpleIDEModelWizard"
+            hasPages="true"
+            id="org.eclipse.e4.demo.tools.simpleide3x.wizard1"
+            name="New Simple IDE Model">
+      </wizard>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/src/org/eclipse/e4/demo/tools/simpleide3x/SimpleIDEModelWizard.java b/examples/org.eclipse.e4.demo.tools.simpleide3x/src/org/eclipse/e4/demo/tools/simpleide3x/SimpleIDEModelWizard.java
new file mode 100644
index 0000000..fbe4d11
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/src/org/eclipse/e4/demo/tools/simpleide3x/SimpleIDEModelWizard.java
@@ -0,0 +1,27 @@
+package org.eclipse.e4.demo.tools.simpleide3x;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.e4.internal.tools.wizards.model.BaseApplicationModelWizard;
+import org.eclipse.e4.internal.tools.wizards.model.NewModelFilePage;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ISelection;
+
+public class SimpleIDEModelWizard extends BaseApplicationModelWizard {
+
+	@Override
+	public String getDefaultFileName() {
+		return "Application.e4xmi";
+	}
+
+	@Override
+	protected EObject createInitialModel() {
+		return (EObject) MSimpleideFactory.INSTANCE.createSimpleIDEApplication();
+	}
+
+	@Override
+	protected NewModelFilePage createWizardPage(ISelection selection) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/.classpath b/examples/org.eclipse.e4.demo.views/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.views/.project b/examples/org.eclipse.e4.demo.views/.project
new file mode 100644
index 0000000..4891d5b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.demo.views</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.views/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.views/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2aa81ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri Nov 28 13:21:46 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.views/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.views/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e767e96
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: LegacyViews Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.demo.views;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.e4.demio.views.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.ide;bundle-version="3.5.0",
+ org.eclipse.core.expressions;bundle-version="3.4.100"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: org.eclipse.core.resources
+Bundle-Vendor: Eclipse.org
diff --git a/examples/org.eclipse.e4.demo.views/build.properties b/examples/org.eclipse.e4.demo.views/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/examples/org.eclipse.e4.demo.views/plugin.xml b/examples/org.eclipse.e4.demo.views/plugin.xml
new file mode 100644
index 0000000..bd39fe2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/plugin.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            class="org.eclipse.e4.demio.views.nav.ResourceNavigator"
+            id="LegacyViews.ResourceView"
+            name="ResourceNav"
+            restorable="true">
+      </view>
+   </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/Activator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/Activator.java
new file mode 100644
index 0000000..d2f266c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/Activator.java
@@ -0,0 +1,51 @@
+package org.eclipse.e4.demio.views;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "LegacyViews";
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 * 
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CollapseAllAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CollapseAllAction.java
new file mode 100644
index 0000000..833f1ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CollapseAllAction.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   IBM Corporation - initial API and implementation 
+ *   Sebastian Davids <sdavids@gmx.de> - Collapse all action (25826)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.CollapseAllHandler;
+
+/**
+ * Collapse all project nodes.
+ */
+public class CollapseAllAction extends ResourceNavigatorAction {
+
+    /**
+     * Creates the action.
+     * 
+     * @param navigator the resource navigator
+     * @param label the label for the action
+     */
+    public CollapseAllAction(IResourceNavigator navigator, String label) {
+        super(navigator, label);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                INavigatorHelpContextIds.COLLAPSE_ALL_ACTION);
+        setEnabled(true);
+        setActionDefinitionId(CollapseAllHandler.COMMAND_ID);
+    }
+
+    /*
+     * Implementation of method defined on <code>IAction</code>.
+     */
+    public void run() {
+        getNavigator().getViewer().collapseAll();
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CopyAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CopyAction.java
new file mode 100644
index 0000000..8e799fb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CopyAction.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.SelectionListenerAction;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Standard action for copying the currently selected resources to the clipboard.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+/*package*/class CopyAction extends SelectionListenerAction {
+
+    /**
+     * The id of this action.
+     */
+    public static final String ID = PlatformUI.PLUGIN_ID + ".CopyAction"; //$NON-NLS-1$
+
+    /**
+     * The shell in which to show any dialogs.
+     */
+    private Shell shell;
+
+    /**
+     * System clipboard
+     */
+    private Clipboard clipboard;
+
+    /**
+     * Associated paste action. May be <code>null</code>
+     */
+    private PasteAction pasteAction;
+
+    /**
+     * Creates a new action.
+     *
+     * @param shell the shell for any dialogs
+     * @param clipboard a platform clipboard
+     */
+    public CopyAction(Shell shell, Clipboard clipboard) {
+        super(ResourceNavigatorMessages.CopyAction_title);
+        Assert.isNotNull(shell);
+        Assert.isNotNull(clipboard);
+        this.shell = shell;
+        this.clipboard = clipboard;
+        setToolTipText(ResourceNavigatorMessages.CopyAction_toolTip);
+        setId(CopyAction.ID);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+				INavigatorHelpContextIds.COPY_ACTION);
+    }
+
+    /**
+     * Creates a new action.
+     *
+     * @param shell the shell for any dialogs
+     * @param clipboard a platform clipboard
+     * @param pasteAction a paste action
+     * 
+     * @since 2.0
+     */
+    public CopyAction(Shell shell, Clipboard clipboard, PasteAction pasteAction) {
+        this(shell, clipboard);
+        this.pasteAction = pasteAction;
+    }
+
+   
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.action.Action#run()
+     */
+    public void run() {
+    	 /**
+         * The <code>CopyAction</code> implementation of this method defined 
+         * on <code>IAction</code> copies the selected resources to the 
+         * clipboard.
+         */
+        List selectedResources = getSelectedResources();
+        IResource[] resources = (IResource[]) selectedResources
+                .toArray(new IResource[selectedResources.size()]);
+
+        // Get the file names and a string representation
+        final int length = resources.length;
+        int actualLength = 0;
+        String[] fileNames = new String[length];
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < length; i++) {
+            IPath location = resources[i].getLocation();
+            // location may be null. See bug 29491.
+            if (location != null) {
+				fileNames[actualLength++] = location.toOSString();
+			}
+            if (i > 0) {
+				buf.append("\n"); //$NON-NLS-1$
+			}
+            buf.append(resources[i].getName());
+        }
+        // was one or more of the locations null?
+        if (actualLength < length) {
+            String[] tempFileNames = fileNames;
+            fileNames = new String[actualLength];
+            for (int i = 0; i < actualLength; i++) {
+				fileNames[i] = tempFileNames[i];
+			}
+        }
+        setClipboard(resources, fileNames, buf.toString());
+
+        // update the enablement of the paste action
+        // workaround since the clipboard does not suppot callbacks
+        if (pasteAction != null && pasteAction.getStructuredSelection() != null) {
+			pasteAction.selectionChanged(pasteAction.getStructuredSelection());
+		}
+    }
+
+    /**
+     * Set the clipboard contents. Prompt to retry if clipboard is busy.
+     * 
+     * @param resources the resources to copy to the clipboard
+     * @param fileNames file names of the resources to copy to the clipboard
+     * @param names string representation of all names
+     */
+    private void setClipboard(IResource[] resources, String[] fileNames,
+            String names) {
+        try {
+            // set the clipboard contents
+            if (fileNames.length > 0) {
+                clipboard.setContents(new Object[] { resources, fileNames,
+                        names },
+                        new Transfer[] { ResourceTransfer.getInstance(),
+                                FileTransfer.getInstance(),
+                                TextTransfer.getInstance() });
+            } else {
+                clipboard.setContents(new Object[] { resources, names },
+                        new Transfer[] { ResourceTransfer.getInstance(),
+                                TextTransfer.getInstance() });
+            }
+        } catch (SWTError e) {
+            if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) {
+				throw e;
+			}
+            if (MessageDialog
+                    .openQuestion(
+                            shell,
+                            ResourceNavigatorMessages.CopyToClipboardProblemDialog_title, ResourceNavigatorMessages.CopyToClipboardProblemDialog_message)) {
+				setClipboard(resources, fileNames, names);
+			}
+        }
+    }
+
+   
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.actions.BaseSelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
+     */
+    protected boolean updateSelection(IStructuredSelection selection) {
+    	
+    	 /**
+         * The <code>CopyAction</code> implementation of this
+         * <code>SelectionListenerAction</code> method enables this action if 
+         * one or more resources of compatible types are selected.
+         */
+    	
+        if (!super.updateSelection(selection)) {
+			return false;
+		}
+
+        if (getSelectedNonResources().size() > 0) {
+			return false;
+		}
+
+        List selectedResources = getSelectedResources();
+        if (selectedResources.size() == 0) {
+			return false;
+		}
+
+        boolean projSelected = selectionIsOfType(IResource.PROJECT);
+        boolean fileFoldersSelected = selectionIsOfType(IResource.FILE
+                | IResource.FOLDER);
+        if (!projSelected && !fileFoldersSelected) {
+			return false;
+		}
+
+        // selection must be homogeneous
+        if (projSelected && fileFoldersSelected) {
+			return false;
+		}
+
+        // must have a common parent	
+        IContainer firstParent = ((IResource) selectedResources.get(0))
+                .getParent();
+        if (firstParent == null) {
+			return false;
+		}
+
+        Iterator resourcesEnum = selectedResources.iterator();
+        while (resourcesEnum.hasNext()) {
+            IResource currentResource = (IResource) resourcesEnum.next();
+            if (!currentResource.getParent().equals(firstParent)) {
+				return false;
+			}
+        }
+
+        return true;
+    }
+
+}
+
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FilterSelectionAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FilterSelectionAction.java
new file mode 100644
index 0000000..505903a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FilterSelectionAction.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * The FilterSelectionAction opens the filters dialog.
+ */
+public class FilterSelectionAction extends ResourceNavigatorAction {
+    private static final String FILTER_TOOL_TIP = ResourceNavigatorMessages.FilterSelection_toolTip;
+
+    private static final String FILTER_SELECTION_MESSAGE = ResourceNavigatorMessages.FilterSelection_message;
+
+    private static final String FILTER_TITLE_MESSAGE = ResourceNavigatorMessages.FilterSelection_title;
+
+    /**
+     * Creates the action.
+     * 
+     * @param navigator the resource navigator
+     * @param label the label for the action
+     */
+    public FilterSelectionAction(IResourceNavigator navigator, String label) {
+        super(navigator, label);
+        setToolTipText(FILTER_TOOL_TIP);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                INavigatorHelpContextIds.FILTER_SELECTION_ACTION);
+        setEnabled(true);
+    }
+
+    /*
+     * Implementation of method defined on <code>IAction</code>.
+     */
+    public void run() {
+        IResourceNavigator navigator = getNavigator();
+        ResourcePatternFilter filter = navigator.getPatternFilter();
+        FiltersContentProvider contentProvider = new FiltersContentProvider(
+                filter);
+
+        ListSelectionDialog dialog = new ListSelectionDialog(getShell(),
+                getViewer(), contentProvider, new LabelProvider(),
+                FILTER_SELECTION_MESSAGE);
+
+        dialog.setTitle(FILTER_TITLE_MESSAGE);
+        dialog.setInitialSelections(contentProvider.getInitialSelections());
+        dialog.open();
+        if (dialog.getReturnCode() == Window.OK) {
+            Object[] results = dialog.getResult();
+            String[] selectedPatterns = new String[results.length];
+            System.arraycopy(results, 0, selectedPatterns, 0, results.length);
+            filter.setPatterns(selectedPatterns);
+            navigator.setFiltersPreference(selectedPatterns);
+            Viewer viewer = getViewer();
+            viewer.getControl().setRedraw(false);
+            viewer.refresh();
+            viewer.getControl().setRedraw(true);
+        }
+    }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FiltersContentProvider.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FiltersContentProvider.java
new file mode 100644
index 0000000..36804e4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FiltersContentProvider.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * The FiltersContentProvider provides the elements for use by the list dialog
+ * for selecting the patterns to apply.
+ */
+/* package */class FiltersContentProvider implements
+        IStructuredContentProvider {
+
+    private static List definedFilters;
+
+    private static List defaultFilters;
+
+    private ResourcePatternFilter resourceFilter;
+
+    /**
+     * Create a FiltersContentProvider using the selections from the supplied
+     * resource filter.
+     * 
+     * @param filter the resource pattern filter 
+     */
+    public FiltersContentProvider(ResourcePatternFilter filter) {
+        this.resourceFilter = filter;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IContentProvider.
+     */
+    public void dispose() {
+    }
+
+    /**
+     * Returns the filters which are enabled by default.
+     *
+     * @return a list of strings
+     */
+    public static List getDefaultFilters() {
+        if (defaultFilters == null) {
+            readFilters();
+        }
+        return defaultFilters;
+    }
+
+    /**
+     * Returns the filters currently defined for the navigator.
+     *
+     * @return a list of strings
+     */
+    public static List getDefinedFilters() {
+        if (definedFilters == null) {
+            readFilters();
+        }
+        return definedFilters;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IStructuredContentProvider.
+     */
+    public Object[] getElements(Object inputElement) {
+        return getDefinedFilters().toArray();
+    }
+
+    /**
+     * Return the initially selected elements.
+     * 
+     * @return an array with the initial selections 
+     */
+    public String[] getInitialSelections() {
+        return this.resourceFilter.getPatterns();
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IContentProvider.
+     */
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+    }
+
+    /**
+     * Reads the filters currently defined for the workbench. 
+     */
+    private static void readFilters() {
+		definedFilters = new ArrayList();
+		defaultFilters = new ArrayList();
+		IExtensionPoint extension = Platform.getExtensionRegistry()
+				.getExtensionPoint(IDEWorkbenchPlugin.IDE_WORKBENCH + '.' 
+						+ ResourcePatternFilter.FILTERS_TAG);
+		if (extension != null) {
+			IExtension[] extensions = extension.getExtensions();
+			for (int i = 0; i < extensions.length; i++) {
+				IConfigurationElement[] configElements = extensions[i]
+						.getConfigurationElements();
+				for (int j = 0; j < configElements.length; j++) {
+					String pattern = configElements[j].getAttribute("pattern");//$NON-NLS-1$
+					if (pattern != null) {
+						definedFilters.add(pattern);
+					}
+					String selected = configElements[j]
+							.getAttribute("selected");//$NON-NLS-1$
+					if (selected != null && selected.equalsIgnoreCase("true")) { //$NON-NLS-1$
+						defaultFilters.add(pattern);
+					}
+				}
+
+			}
+		}
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoActionGroup.java
new file mode 100644
index 0000000..b07e4c2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoActionGroup.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.views.framelist.BackAction;
+import org.eclipse.ui.views.framelist.ForwardAction;
+import org.eclipse.ui.views.framelist.FrameList;
+import org.eclipse.ui.views.framelist.GoIntoAction;
+import org.eclipse.ui.views.framelist.UpAction;
+
+/**
+ * This is the action group for the goto actions.
+ */
+public class GotoActionGroup extends ResourceNavigatorActionGroup {
+
+    private BackAction backAction;
+
+    private ForwardAction forwardAction;
+
+    private GoIntoAction goIntoAction;
+
+    private UpAction upAction;
+
+    private GotoResourceAction goToResourceAction;
+
+    public GotoActionGroup(IResourceNavigator navigator) {
+        super(navigator);
+    }
+
+    public void fillContextMenu(IMenuManager menu) {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+        if (selection.size() == 1) {
+            if (ResourceSelectionUtil.allResourcesAreOfType(selection,
+                    IResource.FOLDER)) {
+                menu.add(goIntoAction);
+            } else {
+                IStructuredSelection resourceSelection = ResourceSelectionUtil
+                        .allResources(selection, IResource.PROJECT);
+                if (resourceSelection != null && !resourceSelection.isEmpty()) {
+                    IProject project = (IProject) resourceSelection
+                            .getFirstElement();
+                    if (project.isOpen()) {
+						menu.add(goIntoAction);
+					}
+                }
+            }
+        }
+    }
+
+    public void fillActionBars(IActionBars actionBars) {
+        actionBars.setGlobalActionHandler(IWorkbenchActionConstants.GO_INTO,
+                goIntoAction);
+        actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(),
+                backAction);
+        actionBars.setGlobalActionHandler(ActionFactory.FORWARD.getId(),
+                forwardAction);
+        actionBars.setGlobalActionHandler(IWorkbenchActionConstants.UP,
+                upAction);
+        actionBars.setGlobalActionHandler(
+                IWorkbenchActionConstants.GO_TO_RESOURCE, goToResourceAction);
+
+        IToolBarManager toolBar = actionBars.getToolBarManager();
+        toolBar.add(backAction);
+        toolBar.add(forwardAction);
+        toolBar.add(upAction);
+    }
+
+    protected void makeActions() {
+        FrameList frameList = navigator.getFrameList();
+        goIntoAction = new GoIntoAction(frameList);
+        backAction = new BackAction(frameList);
+        forwardAction = new ForwardAction(frameList);
+        upAction = new UpAction(frameList);
+        goToResourceAction = new GotoResourceAction(navigator,
+                ResourceNavigatorMessages.GoToResource_label);
+    }
+
+    public void updateActionBars() {
+        ActionContext context = getContext();
+        boolean enable = false;
+
+        // Fix for bug 26126. Resource change listener could call
+        // updateActionBars without a context being set.
+        // This should never happen because resource navigator sets
+        // context immediately after this group is created.
+        if (context != null) {
+            IStructuredSelection selection = (IStructuredSelection) context
+                    .getSelection();
+
+            if (selection.size() == 1) {
+                Object object = selection.getFirstElement();
+                if (object instanceof IProject) {
+                    enable = ((IProject) object).isOpen();
+                } else if (object instanceof IFolder) {
+                    enable = true;
+                }
+            }
+        }
+        goIntoAction.setEnabled(enable);
+        // the rest of the actions update by listening to frame list changes
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceAction.java
new file mode 100644
index 0000000..5c3dd90
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceAction.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Implements the go to resource action. Opens a dialog and set
+ * the navigator selection with the resource selected by
+ * the user.
+ */
+public class GotoResourceAction extends ResourceNavigatorAction {
+    /**
+     * Creates a new instance of the class.
+     * 
+     * @param navigator the navigator
+     * @param label the label
+     * @since 2.0
+     */
+    public GotoResourceAction(IResourceNavigator navigator, String label) {
+        super(navigator, label);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                INavigatorHelpContextIds.GOTO_RESOURCE_ACTION);
+    }
+
+    /**
+     * Collect all resources in the workbench open a dialog asking
+     * the user to select a resource and change the selection in
+     * the navigator.
+     */
+    public void run() {
+        IContainer container = (IContainer) getViewer().getInput();
+        GotoResourceDialog dialog = new GotoResourceDialog(getShell(),
+                container, IResource.FILE | IResource.FOLDER
+                        | IResource.PROJECT);
+        dialog.open();
+        Object[] result = dialog.getResult();
+        if (result == null || result.length == 0
+                || result[0] instanceof IResource == false) {
+			return;
+		}
+
+        IResource selection = (IResource) result[0];
+        getViewer().setSelection(new StructuredSelection(selection), true);
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceDialog.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceDialog.java
new file mode 100644
index 0000000..8dac66f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceDialog.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * Shows a list of resources to the user with a text entry field for a string
+ * pattern used to filter the list of resources.
+ * 
+ */
+/* package */class GotoResourceDialog extends FilteredResourcesSelectionDialog {
+
+	/**
+	 * Creates a new instance of the class.
+	 */
+	protected GotoResourceDialog(Shell parentShell, IContainer container,
+			int typesMask) {
+		super(parentShell, false, container, typesMask);
+		setTitle(ResourceNavigatorMessages.Goto_title);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(parentShell,
+				INavigatorHelpContextIds.GOTO_RESOURCE_DIALOG);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/INavigatorHelpContextIds.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/INavigatorHelpContextIds.java
new file mode 100644
index 0000000..c89fbfb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/INavigatorHelpContextIds.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   IBM Corporation - initial API and implementation 
+ *   Sebastian Davids <sdavids@gmx.de> - Collapse all action (25826)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Help context ids for the resource navigator view.
+ * <p>
+ * This interface contains constants only; it is not intended to be implemented
+ * or extended.
+ * </p>
+ * 
+ */
+/*package*/interface INavigatorHelpContextIds {
+    public static final String PREFIX = PlatformUI.PLUGIN_ID + "."; //$NON-NLS-1$
+
+    // Actions
+    public static final String FILTER_SELECTION_ACTION = PREFIX
+            + "filter_selection_action_context"; //$NON-NLS-1$
+
+    public static final String GOTO_RESOURCE_ACTION = PREFIX
+            + "goto_resource_action_context"; //$NON-NLS-1$
+
+    public static final String RESOURCE_NAVIGATOR_MOVE_ACTION = PREFIX
+            + "resource_navigator_move_action_context"; //$NON-NLS-1$
+
+    public static final String RESOURCE_NAVIGATOR_RENAME_ACTION = PREFIX
+            + "resource_navigator_rename_action_context"; //$NON-NLS-1$
+
+    public static final String SHOW_IN_NAVIGATOR_ACTION = PREFIX
+            + "show_in_navigator_action_context"; //$NON-NLS-1$
+
+    public static final String SORT_VIEW_ACTION = PREFIX
+            + "sort_view_action_context"; //$NON-NLS-1$
+
+    public static final String COPY_ACTION = PREFIX
+            + "resource_navigator_copy_action_context"; //$NON-NLS-1$
+
+    public static final String PASTE_ACTION = PREFIX
+            + "resource_navigator_paste_action_context"; //$NON-NLS-1$
+
+    public static final String COLLAPSE_ALL_ACTION = PREFIX
+            + "collapse_all_action_context"; //$NON-NLS-1$
+
+    // Dialogs
+    public static final String GOTO_RESOURCE_DIALOG = PREFIX
+            + "goto_resource_dialog_context"; //$NON-NLS-1$
+
+    // Views
+    public static final String RESOURCE_VIEW = PREFIX + "resource_view_context"; //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/IResourceNavigator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/IResourceNavigator.java
new file mode 100644
index 0000000..81adb44
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/IResourceNavigator.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.views.framelist.FrameList;
+
+/**
+ * This interface defines the API for the resource navigator.
+ * The action groups should restrict themselves to using this API.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * Subclass <code>org.eclipse.ui.views.ResourceNavigator</code> 
+ * instead.   
+ * </p>
+ * 
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IResourceNavigator extends IViewPart {
+
+    /**
+     * Returns the pattern filter.
+     *
+     * @return the pattern filter
+     */
+    ResourcePatternFilter getPatternFilter();
+
+    /**
+     * Returns the active working set, or <code>null<code> if none.
+     *
+     * @return the active working set, or <code>null<code> if none
+     * @since 2.0
+     */
+    IWorkingSet getWorkingSet();
+
+    /**
+     * Returns the current sorter.
+     * @return the resource navigator's sorter
+     * 
+     * @deprecated as of 3.3, use {@link IResourceNavigator#getComparator()} instead
+     */
+    ResourceSorter getSorter();
+
+    /**
+     * Sets the current sorter.
+     * @param sorter the sorter to use
+     * 
+     * @deprecated as of 3.3, use {@link IResourceNavigator#setComparator(ResourceComparator)} instead
+     */
+    void setSorter(ResourceSorter sorter);
+
+    /**
+     * Returns the current comparator.
+     * 
+     * @return the resource navigator's comparator
+     * @since 3.3
+     */
+    ResourceComparator getComparator();
+
+    /**
+     * Sets the current comparator.
+     * 
+     * @param comparator the comparator to use
+     * @since 3.3
+     */
+    void setComparator(ResourceComparator comparator);
+    
+    /**
+     * Sets the values of the filter preference to be the 
+     * strings in preference values.
+     * @param patterns filter patterns to use on contents of the resource navigator
+     */
+    void setFiltersPreference(String[] patterns);
+
+    /**
+     * Returns the viewer which shows the resource tree.
+     * @return the resource navigator's tree viewer
+     */
+    TreeViewer getViewer();
+
+    /**
+     * Returns the frame list for this navigator.
+     * @return the list of frames maintained by the resource navigator 
+     */
+    FrameList getFrameList();
+
+    /**
+     * Returns whether this navigator's selection automatically tracks the active editor.
+     * 
+     * @return <code>true</code> if linking is enabled, <code>false</code> if not
+     * @since 2.1
+     */
+    boolean isLinkingEnabled();
+
+    /**
+     * Sets the working set for this view, or <code>null</code> to clear it.
+     * 
+     * @param workingSet the working set, or <code>null</code> to clear it
+     * @since 2.0
+     */
+    void setWorkingSet(IWorkingSet workingSet);
+
+    /**
+     * Sets whether this navigator's selection automatically tracks the active editor.
+     * 
+     * @param enabled <code>true</code> to enable, <code>false</code> to disable
+     * @since 2.1
+     */
+    void setLinkingEnabled(boolean enabled);
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/LocalSelectionTransfer.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/LocalSelectionTransfer.java
new file mode 100644
index 0000000..5336090
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/LocalSelectionTransfer.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.dnd.TransferData;
+
+/**
+ * A LocalSelectionTransfer may be used for drag and drop operations within the
+ * same instance of Eclipse. The selection is made available directly for use in
+ * the DropTargetListener. dropAccept method. The DropTargetEvent passed to
+ * dropAccept does not contain the drop data. The selection may be used for
+ * validation purposes so that the drop can be aborted if appropriate. This
+ * class is not intended to be subclassed.
+ * 
+ * @since 2.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class LocalSelectionTransfer extends
+		org.eclipse.jface.util.LocalSelectionTransfer {
+
+	private static final LocalSelectionTransfer INSTANCE = new LocalSelectionTransfer();
+
+	/**
+	 * The get/set methods delegate to JFace's LocalSelectionTransfer to allow
+	 * data to be exchanged freely whether the client uses this
+	 * LocalSelectionTransfer or JFace's LocalSelectionTransfer. Protected
+	 * methods such as getTypeIds() are handled via inheritance, not delegation
+	 * due to visibility constraints.
+	 */
+	private org.eclipse.jface.util.LocalSelectionTransfer jfaceTransfer = org.eclipse.jface.util.LocalSelectionTransfer
+			.getTransfer();
+
+	/**
+	 * Only the singleton instance of this class may be used.
+	 */
+	private LocalSelectionTransfer() {
+	}
+
+	/**
+	 * Returns the singleton.
+	 * 
+	 * @return the singleton
+	 */
+	public static LocalSelectionTransfer getInstance() {
+		return INSTANCE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.util.LocalSelectionTransfer#getSelection()
+	 */
+	public ISelection getSelection() {
+		return jfaceTransfer.getSelection();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.util.LocalSelectionTransfer#getSelectionSetTime()
+	 */
+	public long getSelectionSetTime() {
+		return jfaceTransfer.getSelectionSetTime();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.util.LocalSelectionTransfer#setSelection(org.eclipse.jface.viewers.ISelection)
+	 */
+	public void setSelection(ISelection s) {
+		jfaceTransfer.setSelection(s);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.util.LocalSelectionTransfer#setSelectionSetTime(long)
+	 */
+	public void setSelectionSetTime(long time) {
+		jfaceTransfer.setSelectionSetTime(time);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.util.LocalSelectionTransfer#javaToNative(java.lang.Object, org.eclipse.swt.dnd.TransferData)
+	 */
+	public void javaToNative(Object object, TransferData transferData) {
+		jfaceTransfer.javaToNative(object, transferData);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.util.LocalSelectionTransfer#nativeToJava(org.eclipse.swt.dnd.TransferData)
+	 */
+	public Object nativeToJava(TransferData transferData) {
+		return jfaceTransfer.nativeToJava(transferData);
+	}
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/MainActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/MainActionGroup.java
new file mode 100644
index 0000000..ced7aeb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/MainActionGroup.java
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sebastian Davids <sdavids@gmx.de> - Collapse all action (25826)
+ *     Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.AddBookmarkAction;
+import org.eclipse.ui.actions.AddTaskAction;
+import org.eclipse.ui.actions.ExportResourcesAction;
+import org.eclipse.ui.actions.ImportResourcesAction;
+import org.eclipse.ui.actions.NewWizardMenu;
+import org.eclipse.ui.actions.WorkingSetFilterActionGroup;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.operations.UndoRedoActionGroup;
+
+/**
+ * The main action group for the navigator.
+ * This contains a few actions and several subgroups.
+ */
+public class MainActionGroup extends ResourceNavigatorActionGroup {
+
+    protected AddBookmarkAction addBookmarkAction;
+
+    protected AddTaskAction addTaskAction;
+
+    protected PropertyDialogAction propertyDialogAction;
+
+    protected ImportResourcesAction importAction;
+    
+    protected ExportResourcesAction exportAction;
+
+    protected CollapseAllAction collapseAllAction;
+
+    protected ToggleLinkingAction toggleLinkingAction;
+
+    protected GotoActionGroup gotoGroup;
+
+    protected OpenActionGroup openGroup;
+
+    protected RefactorActionGroup refactorGroup;
+
+    protected WorkingSetFilterActionGroup workingSetGroup;
+
+    protected SortAndFilterActionGroup sortAndFilterGroup;
+    
+    protected UndoRedoActionGroup undoRedoGroup;
+
+    protected WorkspaceActionGroup workspaceGroup;
+
+    private IResourceChangeListener resourceChangeListener;
+
+    private NewWizardMenu newWizardMenu;
+
+    /**
+     * Constructs the main action group.
+     * 
+     * @param navigator the navigator view
+     */
+    public MainActionGroup(IResourceNavigator navigator) {
+        super(navigator);
+        resourceChangeListener = new IResourceChangeListener() {
+            public void resourceChanged(IResourceChangeEvent event) {
+                handleResourceChanged(event);
+            }
+        };
+        ResourcesPlugin.getWorkspace().addResourceChangeListener(
+                resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
+        makeSubGroups();
+    }
+
+    /**
+     * Handles a resource changed event by updating the enablement
+     * if one of the selected projects is opened or closed.
+     */
+    protected void handleResourceChanged(IResourceChangeEvent event) {
+        ActionContext context = getContext();
+        if (context == null) {
+            return;
+        }
+
+        final IStructuredSelection selection = (IStructuredSelection) context
+                .getSelection();
+        if (ResourceSelectionUtil.allResourcesAreOfType(selection,
+                IResource.PROJECT) == false) {
+            return;
+        }
+        List sel = selection.toList();
+        IResourceDelta delta = event.getDelta();
+        if (delta == null) {
+            return;
+        }
+        IResourceDelta[] projDeltas = delta
+                .getAffectedChildren(IResourceDelta.CHANGED);
+        for (int i = 0; i < projDeltas.length; ++i) {
+            IResourceDelta projDelta = projDeltas[i];
+            //changing the project open state or description will effect open/close/build action enablement
+            if ((projDelta.getFlags() & (IResourceDelta.OPEN | IResourceDelta.DESCRIPTION)) != 0) {
+                if (sel.contains(projDelta.getResource())) {
+                    getNavigator().getSite().getShell().getDisplay().syncExec(
+                            new Runnable() {
+                                public void run() {
+                                    addTaskAction.selectionChanged(selection);
+                                    gotoGroup.updateActionBars();
+                                    refactorGroup.updateActionBars();
+                                    workspaceGroup.updateActionBars();
+                                }
+                            });
+                }
+            }
+        }
+    }
+
+    /**
+     * Makes the actions contained directly in this action group.
+     */
+    protected void makeActions() {
+        IShellProvider provider = navigator.getSite();
+
+        newWizardMenu = new NewWizardMenu(navigator.getSite().getWorkbenchWindow());
+        addBookmarkAction = new AddBookmarkAction(provider, true);
+        addTaskAction = new AddTaskAction(provider);
+        propertyDialogAction = new PropertyDialogAction(provider, navigator
+                .getViewer());
+
+        importAction = new ImportResourcesAction(navigator.getSite()
+                .getWorkbenchWindow());
+        importAction
+                .setDisabledImageDescriptor(getImageDescriptor("dtool16/import_wiz.gif")); //$NON-NLS-1$
+        importAction
+                .setImageDescriptor(getImageDescriptor("etool16/import_wiz.gif")); //$NON-NLS-1$		
+
+        exportAction = new ExportResourcesAction(navigator.getSite()
+                .getWorkbenchWindow());
+        exportAction
+                .setDisabledImageDescriptor(getImageDescriptor("dtool16/export_wiz.gif")); //$NON-NLS-1$
+        exportAction
+                .setImageDescriptor(getImageDescriptor("etool16/export_wiz.gif")); //$NON-NLS-1$		
+        
+        
+        collapseAllAction = new CollapseAllAction(navigator,
+                ResourceNavigatorMessages.CollapseAllAction_title);
+        collapseAllAction.setToolTipText(ResourceNavigatorMessages.CollapseAllAction_toolTip);
+        collapseAllAction
+                .setImageDescriptor(getImageDescriptor("elcl16/collapseall.gif")); //$NON-NLS-1$
+
+        toggleLinkingAction = new ToggleLinkingAction(navigator,
+                ResourceNavigatorMessages.ToggleLinkingAction_text);
+        toggleLinkingAction.setToolTipText(ResourceNavigatorMessages.ToggleLinkingAction_toolTip);
+        toggleLinkingAction
+                .setImageDescriptor(getImageDescriptor("elcl16/synced.gif"));//$NON-NLS-1$
+    }
+
+    /**
+     * Makes the sub action groups.
+     */
+    protected void makeSubGroups() {
+        gotoGroup = new GotoActionGroup(navigator);
+        openGroup = new OpenActionGroup(navigator);
+        refactorGroup = new RefactorActionGroup(navigator);
+        IPropertyChangeListener workingSetUpdater = new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                String property = event.getProperty();
+
+                if (WorkingSetFilterActionGroup.CHANGE_WORKING_SET
+                        .equals(property)) {
+                    IResourceNavigator navigator = getNavigator();
+                    Object newValue = event.getNewValue();
+
+                    if (newValue instanceof IWorkingSet) {
+                        navigator.setWorkingSet((IWorkingSet) newValue);
+                    } else if (newValue == null) {
+                        navigator.setWorkingSet(null);
+                    }
+                }
+            }
+        };
+        TreeViewer treeView = navigator.getViewer();
+        Shell shell = treeView.getControl().getShell();
+        workingSetGroup = new WorkingSetFilterActionGroup(shell,
+                workingSetUpdater);
+        workingSetGroup.setWorkingSet(navigator.getWorkingSet());
+        sortAndFilterGroup = new SortAndFilterActionGroup(navigator);
+        workspaceGroup = new WorkspaceActionGroup(navigator);
+        IUndoContext workspaceContext= (IUndoContext)ResourcesPlugin.getWorkspace().getAdapter(IUndoContext.class);
+		undoRedoGroup= new UndoRedoActionGroup(getNavigator().getSite(), workspaceContext, true);
+
+    }
+    
+    /**
+     * Extends the superclass implementation to set the context in the subgroups.
+     */
+    public void setContext(ActionContext context) {
+        super.setContext(context);
+        gotoGroup.setContext(context);
+        openGroup.setContext(context);
+        refactorGroup.setContext(context);
+        sortAndFilterGroup.setContext(context);
+        workspaceGroup.setContext(context);
+        undoRedoGroup.setContext(context);
+    }
+
+    /**
+     * Fills the context menu with the actions contained in this group
+     * and its subgroups.
+     * 
+     * @param menu the context menu
+     */
+    public void fillContextMenu(IMenuManager menu) {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+
+        MenuManager newMenu = new MenuManager(ResourceNavigatorMessages.ResourceNavigator_new);
+        menu.add(newMenu);
+        newMenu.add(newWizardMenu);
+
+        gotoGroup.fillContextMenu(menu);
+        openGroup.fillContextMenu(menu);
+        menu.add(new Separator());
+
+        refactorGroup.fillContextMenu(menu);
+        menu.add(new Separator());
+
+        menu.add(importAction);
+        menu.add(exportAction);
+        importAction.selectionChanged(selection);
+        exportAction.selectionChanged(selection);
+        menu.add(new Separator());
+
+        workspaceGroup.fillContextMenu(menu);
+
+        menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+        menu
+                .add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS
+                        + "-end")); //$NON-NLS-1$
+        menu.add(new Separator());
+
+        if (selection.size() == 1) {
+            propertyDialogAction.selectionChanged(selection);
+            menu.add(propertyDialogAction);
+        }
+    }
+
+    /**
+     * Adds the actions in this group and its subgroups to the action bars.
+     */
+    public void fillActionBars(IActionBars actionBars) {
+        actionBars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(),
+                propertyDialogAction);
+        actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(),
+                addBookmarkAction);
+        actionBars.setGlobalActionHandler(IDEActionFactory.ADD_TASK.getId(),
+                addTaskAction);
+
+        gotoGroup.fillActionBars(actionBars);
+        openGroup.fillActionBars(actionBars);
+        refactorGroup.fillActionBars(actionBars);
+        workingSetGroup.fillActionBars(actionBars);
+        sortAndFilterGroup.fillActionBars(actionBars);
+        workspaceGroup.fillActionBars(actionBars);
+        undoRedoGroup.fillActionBars(actionBars);
+
+        IMenuManager menu = actionBars.getMenuManager();
+        menu.add(toggleLinkingAction);
+
+        IToolBarManager toolBar = actionBars.getToolBarManager();
+        toolBar.add(new Separator());
+        toolBar.add(collapseAllAction);
+        toolBar.add(toggleLinkingAction);
+    }
+
+    /**
+     * Updates the actions which were added to the action bars,
+     * delegating to the subgroups as necessary.
+     */
+    public void updateActionBars() {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+        propertyDialogAction.setEnabled(selection.size() == 1);
+        addBookmarkAction.selectionChanged(selection);
+        addTaskAction.selectionChanged(selection);
+
+        gotoGroup.updateActionBars();
+        openGroup.updateActionBars();
+        refactorGroup.updateActionBars();
+        workingSetGroup.updateActionBars();
+        sortAndFilterGroup.updateActionBars();
+        workspaceGroup.updateActionBars();
+        undoRedoGroup.updateActionBars();
+    }
+
+    /**
+     * Runs the default action (open file) by delegating the open group.
+     */
+    public void runDefaultAction(IStructuredSelection selection) {
+        openGroup.runDefaultAction(selection);
+    }
+
+    /**
+     * Handles a key pressed event by invoking the appropriate action,
+     * delegating to the subgroups as necessary.
+     */
+    public void handleKeyPressed(KeyEvent event) {
+        refactorGroup.handleKeyPressed(event);
+        workspaceGroup.handleKeyPressed(event);
+    }
+
+    /**
+     * Extends the superclass implementation to dispose the 
+     * actions in this group and its subgroups.
+     */
+    public void dispose() {
+        ResourcesPlugin.getWorkspace().removeResourceChangeListener(
+                resourceChangeListener);
+
+        newWizardMenu.dispose();
+        collapseAllAction.dispose();
+        importAction.dispose();
+        exportAction.dispose();
+        propertyDialogAction.dispose();
+        toggleLinkingAction.dispose();
+
+        gotoGroup.dispose();
+        openGroup.dispose();
+        refactorGroup.dispose();
+        sortAndFilterGroup.dispose();
+        workingSetGroup.dispose();
+        workspaceGroup.dispose();
+        undoRedoGroup.dispose();
+        super.dispose();
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDragAdapter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDragAdapter.java
new file mode 100644
index 0000000..cb1d2c2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDragAdapter.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.actions.ReadOnlyStateChecker;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * Implements drag behaviour when items are dragged out of the
+ * resource navigator.
+ * 
+ * @since 2.0
+ */
+public class NavigatorDragAdapter extends DragSourceAdapter {
+    private static final String CHECK_MOVE_TITLE = ResourceNavigatorMessages.DragAdapter_title;
+
+    private static final String CHECK_DELETE_MESSAGE = ResourceNavigatorMessages.DragAdapter_checkDeleteMessage;
+
+    ISelectionProvider selectionProvider;
+
+    private TransferData lastDataType;
+
+    /**
+     * Constructs a new drag adapter.
+     * @param provider The selection provider
+     */
+    public NavigatorDragAdapter(ISelectionProvider provider) {
+        selectionProvider = provider;
+    }
+
+    /**
+     * This implementation of {@link DragSourceListener#dragFinished(DragSourceEvent)}
+     * responds to a drag that has moved resources outside the Navigator by deleting
+     * the corresponding source resource.
+     */
+    public void dragFinished(DragSourceEvent event) {
+        LocalSelectionTransfer.getInstance().setSelection(null);
+
+        if (event.doit == false) {
+			return;
+		}
+
+        final int typeMask = IResource.FOLDER | IResource.FILE;
+        if (event.detail == DND.DROP_MOVE) {
+            //never delete resources when dragging outside Eclipse. 
+            //workaround for bug 30543.
+            if (lastDataType != null
+                    && FileTransfer.getInstance().isSupportedType(lastDataType)) {
+				return;
+			}
+
+            IResource[] resources = getSelectedResources(typeMask);
+            DragSource dragSource = (DragSource) event.widget;
+            Control control = dragSource.getControl();
+            Shell shell = control.getShell();
+            ReadOnlyStateChecker checker;
+
+            if (resources == null || resources.length == 0) {
+				return;
+			}
+
+            checker = new ReadOnlyStateChecker(shell, CHECK_MOVE_TITLE,
+                    CHECK_DELETE_MESSAGE);
+            resources = checker.checkReadOnlyResources(resources);
+            //delete the old elements
+            for (int i = 0; i < resources.length; i++) {
+                try {
+                    resources[i].delete(IResource.KEEP_HISTORY
+                            | IResource.FORCE, null);
+                } catch (CoreException e) {
+                    StatusManager.getManager().handle(e, IDEWorkbenchPlugin.IDE_WORKBENCH);
+                }
+            }
+        } else if (event.detail == DND.DROP_TARGET_MOVE) {
+            IResource[] resources = getSelectedResources(typeMask);
+
+            // file moved for us by OS, no need to delete the resources, just
+            // update the view
+            if (resources == null) {
+				return;
+			}
+            for (int i = 0; i < resources.length; i++) {
+                try {
+                    resources[i].refreshLocal(IResource.DEPTH_INFINITE, null);
+                } catch (CoreException e) {
+                	 StatusManager.getManager().handle(e, IDEWorkbenchPlugin.IDE_WORKBENCH);
+                }
+            }
+        }
+    }
+
+    /**
+     * This implementation of {@link DragSourceListener#dragSetData(DragSourceEvent)}
+     * sets the drag event data based on the current selection in the Navigator.
+     */
+    public void dragSetData(DragSourceEvent event) {
+        final int typeMask = IResource.FILE | IResource.FOLDER;
+        IResource[] resources = getSelectedResources(typeMask);
+
+        if (resources == null || resources.length == 0) {
+			return;
+		}
+
+        lastDataType = event.dataType;
+        //use local selection transfer if possible
+        if (LocalSelectionTransfer.getInstance()
+                .isSupportedType(event.dataType)) {
+            event.data = LocalSelectionTransfer.getInstance().getSelection();
+            return;
+        }
+        //use resource transfer if possible
+        if (ResourceTransfer.getInstance().isSupportedType(event.dataType)) {
+            event.data = resources;
+            return;
+        }
+        //resort to a file transfer
+        if (!FileTransfer.getInstance().isSupportedType(event.dataType)) {
+			return;
+		}
+
+        // Get the path of each file and set as the drag data
+        final int length = resources.length;
+        int actualLength = 0;
+        String[] fileNames = new String[length];
+        for (int i = 0; i < length; i++) {
+            IPath location = resources[i].getLocation();
+            // location may be null. See bug 29491.
+            if (location != null) {
+				fileNames[actualLength++] = location.toOSString();
+			}
+        }
+        if (actualLength == 0) {
+			return;
+		}
+        // was one or more of the locations null?
+        if (actualLength < length) {
+            String[] tempFileNames = fileNames;
+            fileNames = new String[actualLength];
+            for (int i = 0; i < actualLength; i++) {
+				fileNames[i] = tempFileNames[i];
+			}
+        }
+        event.data = fileNames;
+    }
+
+    /**
+     * This implementation of {@link DragSourceListener#dragStart(DragSourceEvent)}
+     * allows the drag to start if the current Navigator selection contains resources
+     * that can be dragged.
+     */
+    public void dragStart(DragSourceEvent event) {
+        lastDataType = null;
+        // Workaround for 1GEUS9V
+        DragSource dragSource = (DragSource) event.widget;
+        Control control = dragSource.getControl();
+        if (control != control.getDisplay().getFocusControl()) {
+            event.doit = false;
+            return;
+        }
+
+        IStructuredSelection selection = (IStructuredSelection) selectionProvider
+                .getSelection();
+        for (Iterator i = selection.iterator(); i.hasNext();) {
+            Object next = i.next();
+            if (!(next instanceof IFile || next instanceof IFolder)) {
+                event.doit = false;
+                return;
+            }
+        }
+        if (selection.isEmpty()) {
+            event.doit = false;
+            return;
+        }
+        LocalSelectionTransfer.getInstance().setSelection(selection);
+        event.doit = true;
+    }
+
+    private IResource[] getSelectedResources(int resourceTypes) {
+        List resources = new ArrayList();
+        IResource[] result = new IResource[0];
+
+        ISelection selection = selectionProvider.getSelection();
+        if (!(selection instanceof IStructuredSelection) || selection.isEmpty()) {
+            return null;
+        }
+        IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+
+        // loop through list and look for matching items
+        Iterator itr = structuredSelection.iterator();
+        while (itr.hasNext()) {
+            Object obj = itr.next();
+            if (obj instanceof IResource) {
+                IResource res = (IResource) obj;
+                if ((res.getType() & resourceTypes) == res.getType()) {
+                    resources.add(res);
+                }
+            }
+        }
+        result = new IResource[resources.size()];
+        resources.toArray(result);
+        return result;
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDropAdapter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDropAdapter.java
new file mode 100644
index 0000000..3c38ee0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDropAdapter.java
@@ -0,0 +1,422 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
+import org.eclipse.ui.actions.MoveFilesAndFoldersOperation;
+import org.eclipse.ui.actions.ReadOnlyStateChecker;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.PluginDropAdapter;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Implements drop behaviour for drag and drop operations
+ * that land on the resource navigator.
+ * 
+ * @since 2.0
+ */
+public class NavigatorDropAdapter extends PluginDropAdapter implements
+        IOverwriteQuery {
+
+    /**
+     * A flag indicating that overwrites should always occur.
+     */
+    private boolean alwaysOverwrite = false;
+
+    /**
+     * The last valid operation.
+     */
+    private int lastValidOperation = DND.DROP_NONE;
+
+    /**
+     * Constructs a new drop adapter.
+     * 
+     * @param viewer the navigator's viewer
+     */
+    public NavigatorDropAdapter(StructuredViewer viewer) {
+        super(viewer);
+    }
+
+    /*
+     * @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
+     */
+    public void dragEnter(DropTargetEvent event) {
+        if (FileTransfer.getInstance().isSupportedType(event.currentDataType)
+                && event.detail == DND.DROP_DEFAULT) {
+            // default to copy when dragging from outside Eclipse. Fixes bug 16308.
+            event.detail = DND.DROP_COPY;
+        }
+        super.dragEnter(event);
+    }
+
+    /**
+     * Returns an error status with the given info.
+     */
+    private IStatus error(String message) {
+        return error(message, null);
+    }
+
+    /**
+     * Returns an error status with the given info.
+     */
+    private IStatus error(String message, Throwable exception) {
+        return new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message,
+                exception);
+    }
+
+    /**
+     * Returns the actual target of the drop, given the resource
+     * under the mouse.  If the mouse target is a file, then the drop actually 
+     * occurs in its parent.  If the drop location is before or after the
+     * mouse target and feedback is enabled, the target is also the parent.
+     */
+    private IContainer getActualTarget(IResource mouseTarget) {
+        /* if cursor is before or after mouseTarget, set target to parent */
+        if (getFeedbackEnabled()) {
+            if (getCurrentLocation() == LOCATION_BEFORE
+                    || getCurrentLocation() == LOCATION_AFTER) {
+                return mouseTarget.getParent();
+            }
+        }
+        /* if cursor is on a file, return the parent */
+        if (mouseTarget.getType() == IResource.FILE) {
+            return mouseTarget.getParent();
+        }
+        /* otherwise the mouseTarget is the real target */
+        return (IContainer) mouseTarget;
+    }
+
+    /**
+     * Returns the display
+     */
+    private Display getDisplay() {
+        return getViewer().getControl().getDisplay();
+    }
+
+    /**
+     * Returns the resource selection from the LocalSelectionTransfer.
+     * 
+     * @return the resource selection from the LocalSelectionTransfer
+     */
+    private IResource[] getSelectedResources() {
+        ArrayList selectedResources = new ArrayList();
+
+        ISelection selection = LocalSelectionTransfer.getInstance()
+                .getSelection();
+        if (selection instanceof IStructuredSelection) {
+            IStructuredSelection ssel = (IStructuredSelection) selection;
+            for (Iterator i = ssel.iterator(); i.hasNext();) {
+                Object o = i.next();
+                if (o instanceof IResource) {
+                    selectedResources.add(o);
+                }
+                else if (o instanceof IAdaptable) {
+                    IAdaptable a = (IAdaptable) o;
+                    IResource r = (IResource) a.getAdapter(IResource.class);
+                    if (r != null) {
+                        selectedResources.add(r);
+                    }
+                }
+            }
+        }
+        return (IResource[]) selectedResources.toArray(new IResource[selectedResources.size()]);
+    }
+
+    /**
+     * Returns the shell
+     */
+    private Shell getShell() {
+        return getViewer().getControl().getShell();
+    }
+
+    /**
+     * Returns an error status with the given info.
+     */
+    private IStatus info(String message) {
+        return new Status(IStatus.INFO, PlatformUI.PLUGIN_ID, 0, message, null);
+    }
+
+    /**
+     * Adds the given status to the list of problems.  Discards
+     * OK statuses.  If the status is a multi-status, only its children
+     * are added.
+     */
+    private void mergeStatus(MultiStatus status, IStatus toMerge) {
+        if (!toMerge.isOK()) {
+            status.merge(toMerge);
+        }
+    }
+
+    /**
+     * Returns an status indicating success.
+     */
+    private IStatus ok() {
+        return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0,
+                ResourceNavigatorMessages.DropAdapter_ok, null);
+    }
+
+    /**
+     * Opens an error dialog if necessary.  Takes care of
+     * complex rules necessary for making the error dialog look nice.
+     */
+    private void openError(IStatus status) {
+        if (status == null) {
+			return;
+		}
+
+        String genericTitle = ResourceNavigatorMessages.DropAdapter_title;
+        int codes = IStatus.ERROR | IStatus.WARNING;
+
+        //simple case: one error, not a multistatus
+        if (!status.isMultiStatus()) {
+            ErrorDialog
+                    .openError(getShell(), genericTitle, null, status, codes);
+            return;
+        }
+
+        //one error, single child of multistatus
+        IStatus[] children = status.getChildren();
+        if (children.length == 1) {
+            ErrorDialog.openError(getShell(), status.getMessage(), null,
+                    children[0], codes);
+            return;
+        }
+        //several problems
+        ErrorDialog.openError(getShell(), genericTitle, null, status, codes);
+    }
+
+    /**
+     * Perform the drop.
+     * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
+     */
+    public boolean performDrop(final Object data) {
+        alwaysOverwrite = false;
+        if (getCurrentTarget() == null || data == null) {
+            return false;
+        }
+        boolean result = false;
+        IStatus status = null;
+        IResource[] resources = null;
+        TransferData currentTransfer = getCurrentTransfer();
+        if (LocalSelectionTransfer.getInstance().isSupportedType(
+                currentTransfer)) {
+            resources = getSelectedResources();
+        } else if (ResourceTransfer.getInstance().isSupportedType(
+                currentTransfer)) {
+            resources = (IResource[]) data;
+        } else if (FileTransfer.getInstance().isSupportedType(currentTransfer)) {
+            status = performFileDrop(data);
+            result = status.isOK();
+        } else {
+            result = NavigatorDropAdapter.super.performDrop(data);
+        }
+        if (resources != null && resources.length > 0) {
+            if (getCurrentOperation() == DND.DROP_COPY) {
+				status = performResourceCopy(getShell(), resources);
+			} else {
+				status = performResourceMove(resources);
+			}
+        }
+        openError(status);
+        return result;
+    }
+
+    /**
+     * Performs a drop using the FileTransfer transfer type.
+     */
+    private IStatus performFileDrop(Object data) {
+        MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 0,
+                ResourceNavigatorMessages.DropAdapter_problemImporting, null);
+        mergeStatus(problems, validateTarget(getCurrentTarget(),
+                getCurrentTransfer()));
+
+        final IContainer target = getActualTarget((IResource) getCurrentTarget());
+        final String[] names = (String[]) data;
+        // Run the import operation asynchronously. 
+        // Otherwise the drag source (e.g., Windows Explorer) will be blocked 
+        // while the operation executes. Fixes bug 16478.
+        Display.getCurrent().asyncExec(new Runnable() {
+            public void run() {
+                getShell().forceActive();
+                CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+                        getShell());
+                operation.copyFiles(names, target);
+            }
+        });
+        return problems;
+    }
+
+    /**
+     * Performs a resource copy
+     */
+    private IStatus performResourceCopy(Shell shell, IResource[] sources) {
+        MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 1,
+                ResourceNavigatorMessages.DropAdapter_problemsMoving, null);
+        mergeStatus(problems, validateTarget(getCurrentTarget(),
+                getCurrentTransfer()));
+
+        IContainer target = getActualTarget((IResource) getCurrentTarget());
+        CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+                shell);
+        operation.copyResources(sources, target);
+
+        return problems;
+    }
+
+    /**
+     * Performs a resource move
+     */
+    private IStatus performResourceMove(IResource[] sources) {
+        MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 1,
+                ResourceNavigatorMessages.DropAdapter_problemsMoving, null);
+        mergeStatus(problems, validateTarget(getCurrentTarget(),
+                getCurrentTransfer()));
+
+        IContainer target = getActualTarget((IResource) getCurrentTarget());
+        ReadOnlyStateChecker checker = new ReadOnlyStateChecker(
+                getShell(),
+                ResourceNavigatorMessages.MoveResourceAction_title,
+                ResourceNavigatorMessages.MoveResourceAction_checkMoveMessage);
+        sources = checker.checkReadOnlyResources(sources);
+        MoveFilesAndFoldersOperation operation = new MoveFilesAndFoldersOperation(
+                getShell());
+        operation.copyResources(sources, target);
+
+        return problems;
+    }
+
+    /*
+     * @see org.eclipse.ui.dialogs.IOverwriteQuery#queryOverwrite(java.lang.String)
+     */
+    public String queryOverwrite(String pathString) {
+        if (alwaysOverwrite) {
+			return ALL;
+		}
+
+        final String returnCode[] = { CANCEL };
+        final String msg = NLS.bind(ResourceNavigatorMessages.DropAdapter_overwriteQuery, pathString);
+        final String[] options = { IDialogConstants.YES_LABEL,
+                IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL,
+                IDialogConstants.CANCEL_LABEL };
+        getDisplay().syncExec(new Runnable() {
+            public void run() {
+                MessageDialog dialog = new MessageDialog(
+                        getShell(),
+                        ResourceNavigatorMessages.DropAdapter_question, null, msg, MessageDialog.QUESTION, options, 0);
+                dialog.open();
+                int returnVal = dialog.getReturnCode();
+                String[] returnCodes = { YES, ALL, NO, CANCEL };
+                returnCode[0] = returnVal < 0 ? CANCEL : returnCodes[returnVal];
+            }
+        });
+        if (returnCode[0] == ALL) {
+			alwaysOverwrite = true;
+		}
+        return returnCode[0];
+    }
+
+    /**
+     * This method is used to notify the action that some aspect of
+     * the drop operation has changed.
+     */
+    public boolean validateDrop(Object target, int dragOperation,
+            TransferData transferType) {
+
+        if (dragOperation != DND.DROP_NONE) {
+            lastValidOperation = dragOperation;
+        }
+        if (FileTransfer.getInstance().isSupportedType(transferType)
+                && lastValidOperation != DND.DROP_COPY) {
+            // only allow copying when dragging from outside Eclipse
+            return false;
+        }
+        if (super.validateDrop(target, dragOperation, transferType)) {
+            return true;
+        }
+        return validateTarget(target, transferType).isOK();
+    }
+
+    /**
+     * Ensures that the drop target meets certain criteria
+     */
+    private IStatus validateTarget(Object target, TransferData transferType) {
+        if (!(target instanceof IResource)) {
+            return info(ResourceNavigatorMessages.DropAdapter_targetMustBeResource);
+        }
+        IResource resource = (IResource) target;
+        if (!resource.isAccessible()) {
+            return error(ResourceNavigatorMessages.DropAdapter_canNotDropIntoClosedProject);
+        }
+        IContainer destination = getActualTarget(resource);
+        if (destination.getType() == IResource.ROOT) {
+            return error(ResourceNavigatorMessages.DropAdapter_resourcesCanNotBeSiblings);
+        }
+        String message = null;
+        // drag within Eclipse?
+        if (LocalSelectionTransfer.getInstance().isSupportedType(transferType)) {
+            IResource[] selectedResources = getSelectedResources();
+
+            if (selectedResources.length == 0) {
+				message = ResourceNavigatorMessages.DropAdapter_dropOperationErrorOther;
+			} else {
+                CopyFilesAndFoldersOperation operation;
+                if (lastValidOperation == DND.DROP_COPY) {
+                    operation = new CopyFilesAndFoldersOperation(getShell());
+                } else {
+                    operation = new MoveFilesAndFoldersOperation(getShell());
+                }
+                message = operation.validateDestination(destination,
+                        selectedResources);
+            }
+        } // file import?
+        else if (FileTransfer.getInstance().isSupportedType(transferType)) {
+            String[] sourceNames = (String[]) FileTransfer.getInstance()
+                    .nativeToJava(transferType);
+            if (sourceNames == null) {
+                // source names will be null on Linux. Use empty names to do destination validation.
+                // Fixes bug 29778
+                sourceNames = new String[0];
+            }
+            CopyFilesAndFoldersOperation copyOperation = new CopyFilesAndFoldersOperation(
+                    getShell());
+            message = copyOperation.validateImportDestination(destination,
+                    sourceNames);
+        }
+        if (message != null) {
+            return error(message);
+        }
+        return ok();
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorFrameSource.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorFrameSource.java
new file mode 100644
index 0000000..6ba7965
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorFrameSource.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.views.framelist.TreeFrame;
+import org.eclipse.ui.views.framelist.TreeViewerFrameSource;
+
+/**
+ * Frame source for the resource navigator.
+ */
+public class NavigatorFrameSource extends TreeViewerFrameSource {
+
+    private ResourceNavigator navigator;
+
+    /**
+     * Constructs a new frame source for the specified resource navigator.
+     * 
+     * @param navigator the resource navigator
+     */
+    public NavigatorFrameSource(ResourceNavigator navigator) {
+        super(navigator.getTreeViewer());
+        this.navigator = navigator;
+    }
+
+    /**
+     * Returns a new frame.  This implementation extends the super implementation
+     * by setting the frame's tool tip text to show the full path for the input
+     * element.
+     */
+    protected TreeFrame createFrame(Object input) {
+        TreeFrame frame = super.createFrame(input);
+        frame.setName(navigator.getFrameName(input));
+        frame.setToolTipText(navigator.getFrameToolTipText(input));
+        return frame;
+    }
+
+    /**
+     * Also updates the navigator's title.
+     */
+    protected void frameChanged(TreeFrame frame) {
+        IResource resource = (IResource) frame.getInput();
+        IProject project = resource.getProject();
+
+        if (project != null && project.isOpen() == false) {
+            MessageDialog
+                    .openInformation(
+                            navigator.getViewSite().getShell(),
+                            ResourceNavigatorMessages.NavigatorFrameSource_closedProject_title,
+                            NLS.bind(ResourceNavigatorMessages.NavigatorFrameSource_closedProject_message, project.getName()));
+            navigator.getFrameList().back();
+        } else {
+            super.frameChanged(frame);
+            navigator.updateTitle();
+        }
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/OpenActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/OpenActionGroup.java
new file mode 100644
index 0000000..78a9a29
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/OpenActionGroup.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.OpenFileAction;
+import org.eclipse.ui.actions.OpenInNewWindowAction;
+import org.eclipse.ui.actions.OpenWithMenu;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * This is the action group for the open actions.
+ */
+public class OpenActionGroup extends ResourceNavigatorActionGroup {
+
+    private OpenFileAction openFileAction;
+
+    /**
+     * The id for the Open With submenu.
+     */
+    public static final String OPEN_WITH_ID = PlatformUI.PLUGIN_ID
+            + ".OpenWithSubMenu"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new action group for open actions.
+	 * 
+	 * @param navigator the resource navigator
+	 */
+    public OpenActionGroup(IResourceNavigator navigator) {
+        super(navigator);
+    }
+
+    protected void makeActions() {
+        openFileAction = new OpenFileAction(navigator.getSite().getPage());
+    }
+
+    public void fillContextMenu(IMenuManager menu) {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+
+        boolean anyResourceSelected = !selection.isEmpty()
+                && ResourceSelectionUtil.allResourcesAreOfType(selection,
+                        IResource.PROJECT | IResource.FOLDER | IResource.FILE);
+        boolean onlyFilesSelected = !selection.isEmpty()
+                && ResourceSelectionUtil.allResourcesAreOfType(selection,
+                        IResource.FILE);
+
+        if (onlyFilesSelected) {
+            openFileAction.selectionChanged(selection);
+            menu.add(openFileAction);
+            fillOpenWithMenu(menu, selection);
+        }
+
+        if (anyResourceSelected) {
+            addNewWindowAction(menu, selection);
+        }
+    }
+
+    /**
+     * Adds the OpenWith submenu to the context menu.
+     * 
+     * @param menu the context menu
+     * @param selection the current selection
+     */
+    private void fillOpenWithMenu(IMenuManager menu,
+            IStructuredSelection selection) {
+
+        // Only supported if exactly one file is selected.
+        if (selection.size() != 1) {
+			return;
+		}
+        Object element = selection.getFirstElement();
+        if (!(element instanceof IFile)) {
+			return;
+		}
+
+        MenuManager submenu = new MenuManager(ResourceNavigatorMessages.ResourceNavigator_openWith, OPEN_WITH_ID);
+        submenu.add(new OpenWithMenu(navigator.getSite().getPage(),
+                (IFile) element));
+        menu.add(submenu);
+    }
+
+    /**
+     * Adds the Open in New Window action to the context menu.
+     * 
+     * @param menu the context menu
+     * @param selection the current selection
+     */
+    private void addNewWindowAction(IMenuManager menu,
+            IStructuredSelection selection) {
+
+        // Only supported if exactly one container (i.e open project or folder) is selected.
+        if (selection.size() != 1) {
+			return;
+		}
+        Object element = selection.getFirstElement();
+        if (!(element instanceof IContainer)) {
+			return;
+		}
+        if (element instanceof IProject && !(((IProject) element).isOpen())) {
+			return;
+		}
+
+        menu.add(new OpenInNewWindowAction(navigator.getSite()
+                .getWorkbenchWindow(), (IContainer) element));
+    }
+
+    /**
+     * Runs the default action (open file).
+     */
+    public void runDefaultAction(IStructuredSelection selection) {
+        Object element = selection.getFirstElement();
+        if (element instanceof IFile) {
+            openFileAction.selectionChanged(selection);
+            openFileAction.run();
+        }
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/PasteAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/PasteAction.java
new file mode 100644
index 0000000..a304877
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/PasteAction.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
+import org.eclipse.ui.actions.CopyProjectOperation;
+import org.eclipse.ui.actions.SelectionListenerAction;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Standard action for pasting resources on the clipboard to the selected resource's location.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.0
+ */
+/*package*/class PasteAction extends SelectionListenerAction {
+
+    /**
+     * The id of this action.
+     */
+    public static final String ID = PlatformUI.PLUGIN_ID + ".PasteAction";//$NON-NLS-1$
+
+    /**
+     * The shell in which to show any dialogs.
+     */
+    private Shell shell;
+
+    /**
+     * System clipboard
+     */
+    private Clipboard clipboard;
+
+    /**
+     * Creates a new action.
+     *
+     * @param shell the shell for any dialogs
+     * @param clipboard the clipboard
+     */
+    public PasteAction(Shell shell, Clipboard clipboard) {
+        super(ResourceNavigatorMessages.PasteAction_title);
+        Assert.isNotNull(shell);
+        Assert.isNotNull(clipboard);
+        this.shell = shell;
+        this.clipboard = clipboard;
+        setToolTipText(ResourceNavigatorMessages.PasteAction_toolTip);
+        setId(PasteAction.ID);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+				INavigatorHelpContextIds.PASTE_ACTION);
+    }
+
+    /**
+     * Returns the actual target of the paste action. Returns null
+     * if no valid target is selected.
+     * 
+     * @return the actual target of the paste action
+     */
+    private IResource getTarget() {
+        List selectedResources = getSelectedResources();
+
+        for (int i = 0; i < selectedResources.size(); i++) {
+            IResource resource = (IResource) selectedResources.get(i);
+
+            if (resource instanceof IProject && !((IProject) resource).isOpen()) {
+				return null;
+			}
+            if (resource.getType() == IResource.FILE) {
+				resource = resource.getParent();
+			}
+            if (resource != null) {
+				return resource;
+			}
+        }
+        return null;
+    }
+
+    /**
+     * Returns whether any of the given resources are linked resources.
+     * 
+     * @param resources resource to check for linked type. may be null
+     * @return true=one or more resources are linked. false=none of the 
+     * 	resources are linked
+     */
+    private boolean isLinked(IResource[] resources) {
+        for (int i = 0; i < resources.length; i++) {
+            if (resources[i].isLinked()) {
+				return true;
+			}
+        }
+        return false;
+    }
+
+    /**
+     * Implementation of method defined on <code>IAction</code>.
+     */
+    public void run() {
+        // try a resource transfer
+        ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+        IResource[] resourceData = (IResource[]) clipboard
+                .getContents(resTransfer);
+
+        if (resourceData != null && resourceData.length > 0) {
+            if (resourceData[0].getType() == IResource.PROJECT) {
+                // enablement checks for all projects
+                for (int i = 0; i < resourceData.length; i++) {
+                    CopyProjectOperation operation = new CopyProjectOperation(
+                            this.shell);
+                    operation.copyProject((IProject) resourceData[i]);
+                }
+            } else {
+                // enablement should ensure that we always have access to a container
+                IContainer container = getContainer();
+
+                CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+                        this.shell);
+                operation.copyResources(resourceData, container);
+            }
+            return;
+        }
+
+        // try a file transfer
+        FileTransfer fileTransfer = FileTransfer.getInstance();
+        String[] fileData = (String[]) clipboard.getContents(fileTransfer);
+
+        if (fileData != null) {
+            // enablement should ensure that we always have access to a container
+            IContainer container = getContainer();
+
+            CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+                    this.shell);
+            operation.copyFiles(fileData, container);
+        }
+    }
+
+    /**
+     * Returns the container to hold the pasted resources.
+     */
+    private IContainer getContainer() {
+        List selection = getSelectedResources();
+        if (selection.get(0) instanceof IFile) {
+			return ((IFile) selection.get(0)).getParent();
+		} else {
+			return (IContainer) selection.get(0);
+		}
+    }
+
+    /**
+     * The <code>PasteAction</code> implementation of this
+     * <code>SelectionListenerAction</code> method enables this action if 
+     * a resource compatible with what is on the clipboard is selected.
+     * 
+     * -Clipboard must have IResource or java.io.File
+     * -Projects can always be pasted if they are open
+     * -Workspace folder may not be copied into itself
+     * -Files and folders may be pasted to a single selected folder in open 
+     * 	project or multiple selected files in the same folder 
+     */
+    protected boolean updateSelection(IStructuredSelection selection) {
+        if (!super.updateSelection(selection)) {
+			return false;
+		}
+
+        final IResource[][] clipboardData = new IResource[1][];
+        shell.getDisplay().syncExec(new Runnable() {
+            public void run() {
+                // clipboard must have resources or files
+                ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+                clipboardData[0] = (IResource[]) clipboard
+                        .getContents(resTransfer);
+            }
+        });
+        IResource[] resourceData = clipboardData[0];
+        boolean isProjectRes = resourceData != null && resourceData.length > 0
+                && resourceData[0].getType() == IResource.PROJECT;
+
+        if (isProjectRes) {
+            for (int i = 0; i < resourceData.length; i++) {
+                // make sure all resource data are open projects
+                // can paste open projects regardless of selection
+                if (resourceData[i].getType() != IResource.PROJECT
+                        || ((IProject) resourceData[i]).isOpen() == false) {
+					return false;
+				}
+            }
+            return true;
+        }
+
+        if (getSelectedNonResources().size() > 0) {
+			return false;
+		}
+
+        IResource targetResource = getTarget();
+        // targetResource is null if no valid target is selected (e.g., open project) 
+        // or selection is empty	
+        if (targetResource == null) {
+			return false;
+		}
+
+        // can paste files and folders to a single selection (file, folder, 
+        // open project) or multiple file selection with the same parent
+        List selectedResources = getSelectedResources();
+        if (selectedResources.size() > 1) {
+            for (int i = 0; i < selectedResources.size(); i++) {
+                IResource resource = (IResource) selectedResources.get(i);
+                if (resource.getType() != IResource.FILE) {
+					return false;
+				}
+                if (!targetResource.equals(resource.getParent())) {
+					return false;
+				}
+            }
+        }
+        if (resourceData != null) {
+            // linked resources can only be pasted into projects
+            if (isLinked(resourceData)
+                    && targetResource.getType() != IResource.PROJECT
+                    && targetResource.getType() != IResource.FOLDER) {
+				return false;
+			}
+
+            if (targetResource.getType() == IResource.FOLDER) {
+                // don't try to copy folder to self
+                for (int i = 0; i < resourceData.length; i++) {
+                    if (targetResource.equals(resourceData[i])) {
+						return false;
+					}
+                }
+            }
+            return true;
+        }
+        TransferData[] transfers = clipboard.getAvailableTypes();
+        FileTransfer fileTransfer = FileTransfer.getInstance();
+        for (int i = 0; i < transfers.length; i++) {
+            if (fileTransfer.isSupportedType(transfers[i])) {
+				return true;
+			}
+        }
+        return false;
+    }
+}
+
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/RefactorActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/RefactorActionGroup.java
new file mode 100644
index 0000000..ea59952
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/RefactorActionGroup.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.DeleteResourceAction;
+import org.eclipse.ui.actions.TextActionHandler;
+
+/**
+ * This is the action group for refactor actions,
+ * including global action handlers for copy, paste and delete.
+ * 
+ * @since 2.0
+ */
+public class RefactorActionGroup extends ResourceNavigatorActionGroup {
+
+    private Clipboard clipboard;
+
+    private CopyAction copyAction;
+
+    private DeleteResourceAction deleteAction;
+
+    private PasteAction pasteAction;
+
+    private ResourceNavigatorRenameAction renameAction;
+
+    private ResourceNavigatorMoveAction moveAction;
+
+    private TextActionHandler textActionHandler;
+
+    public RefactorActionGroup(IResourceNavigator navigator) {
+        super(navigator);
+    }
+
+    public void dispose() {
+        if (clipboard != null) {
+            clipboard.dispose();
+            clipboard = null;
+        }
+        super.dispose();
+    }
+
+    public void fillContextMenu(IMenuManager menu) {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+
+        boolean anyResourceSelected = !selection.isEmpty()
+                && ResourceSelectionUtil.allResourcesAreOfType(selection,
+                        IResource.PROJECT | IResource.FOLDER | IResource.FILE);
+
+        copyAction.selectionChanged(selection);
+        menu.add(copyAction);
+        pasteAction.selectionChanged(selection);
+        menu.add(pasteAction);
+
+        if (anyResourceSelected) {
+            deleteAction.selectionChanged(selection);
+            menu.add(deleteAction);
+            moveAction.selectionChanged(selection);
+            menu.add(moveAction);
+            renameAction.selectionChanged(selection);
+            menu.add(renameAction);
+        }
+    }
+
+    public void fillActionBars(IActionBars actionBars) {
+        textActionHandler = new TextActionHandler(actionBars); // hooks handlers
+        textActionHandler.setCopyAction(copyAction);
+        textActionHandler.setPasteAction(pasteAction);
+        textActionHandler.setDeleteAction(deleteAction);
+        renameAction.setTextActionHandler(textActionHandler);
+
+        actionBars.setGlobalActionHandler(ActionFactory.MOVE.getId(),
+                moveAction);
+        actionBars.setGlobalActionHandler(ActionFactory.RENAME.getId(),
+                renameAction);
+    }
+
+    /**
+     * Handles a key pressed event by invoking the appropriate action.
+     */
+    public void handleKeyPressed(KeyEvent event) {
+        if (event.character == SWT.DEL && event.stateMask == 0) {
+            if (deleteAction.isEnabled()) {
+                deleteAction.run();
+            }
+
+            // Swallow the event.
+            event.doit = false;
+
+        } else if (event.keyCode == SWT.F2 && event.stateMask == 0) {
+            if (renameAction.isEnabled()) {
+                renameAction.run();
+            }
+
+            // Swallow the event.
+            event.doit = false;
+        }
+    }
+
+    protected void makeActions() {
+        TreeViewer treeViewer = navigator.getViewer();
+        IShellProvider provider = navigator.getSite();
+        clipboard = new Clipboard(provider.getShell().getDisplay());
+
+        pasteAction = new PasteAction(provider.getShell(), clipboard);
+        ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
+        pasteAction.setDisabledImageDescriptor(images
+                .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
+        pasteAction.setImageDescriptor(images
+                .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
+
+        copyAction = new CopyAction(provider.getShell(), clipboard, pasteAction);
+        copyAction.setDisabledImageDescriptor(images
+                .getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED));
+        copyAction.setImageDescriptor(images
+                .getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
+
+        moveAction = new ResourceNavigatorMoveAction(provider.getShell(), treeViewer);
+        renameAction = new ResourceNavigatorRenameAction(provider.getShell(), treeViewer);
+
+        deleteAction = new DeleteResourceAction(provider);
+        deleteAction.setDisabledImageDescriptor(images
+                .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED));
+        deleteAction.setImageDescriptor(images
+                .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
+    }
+
+    public void updateActionBars() {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+
+        copyAction.selectionChanged(selection);
+        pasteAction.selectionChanged(selection);
+        deleteAction.selectionChanged(selection);
+        moveAction.selectionChanged(selection);
+        renameAction.selectionChanged(selection);
+    }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceComparator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceComparator.java
new file mode 100644
index 0000000..dd91b00
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceComparator.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+/**
+ * Comparator for viewers that display items of type <code>IResource</code>.
+ * The sorter supports two sort criteria:
+ * <p>
+ * <code>NAME</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by name.  All name comparisons
+ * are case-insensitive.
+ * </p>
+ * <p>
+ * <code>TYPE</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by extension.  All extension
+ * comparisons are case-insensitive.
+ * </p>
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 3.3
+ */
+public class ResourceComparator extends ViewerComparator {
+
+    /**
+     * Constructor argument value that indicates to sort items by name.
+     */
+    public final static int NAME = 1;
+
+    /**
+     * Constructor argument value that indicates to sort items by extension.
+     */
+    public final static int TYPE = 2;
+
+    private int criteria;
+
+    /**
+     * Creates a resource sorter that will use the given sort criteria.
+     *
+     * @param criteria the sort criterion to use: one of <code>NAME</code> or 
+     *   <code>TYPE</code>
+     */
+    public ResourceComparator(int criteria) {
+        super();
+        this.criteria = criteria;
+    }
+
+    /**
+     * Returns an integer value representing the relative sort priority of the 
+     * given element based on its class.
+     * <p>
+     * <ul>
+     *   <li>resources (<code>IResource</code>) - 2</li>
+     *   <li>project references (<code>ProjectReference</code>) - 1</li>
+     *   <li>everything else - 0</li>
+     * </ul>
+     * </p>
+     *
+     * @param element the element
+     * @return the sort priority (larger numbers means more important)
+     */
+    protected int classComparison(Object element) {
+        if (element instanceof IResource) {
+            return 2;
+        }
+        return 0;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on ViewerComparator.
+     */
+    public int compare(Viewer viewer, Object o1, Object o2) {
+        //have to deal with non-resources in navigator
+        //if one or both objects are not resources, returned a comparison 
+        //based on class.
+        if (!(o1 instanceof IResource && o2 instanceof IResource)) {
+            return compareClass(o1, o2);
+        }
+        IResource r1 = (IResource) o1;
+        IResource r2 = (IResource) o2;
+
+        if (r1 instanceof IContainer && r2 instanceof IContainer) {
+			return compareNames(r1, r2);
+		} else if (r1 instanceof IContainer) {
+			return -1;
+		} else if (r2 instanceof IContainer) {
+			return 1;
+		} else if (criteria == NAME) {
+			return compareNames(r1, r2);
+		} else if (criteria == TYPE) {
+			return compareTypes(r1, r2);
+		} else {
+			return 0;
+		}
+    }
+
+    /**
+     * Returns a number reflecting the collation order of the given elements
+     * based on their class.
+     *
+     * @param element1 the first element to be ordered
+     * @param element2 the second element to be ordered
+     * @return a negative number if the first element is less  than the 
+     *  second element; the value <code>0</code> if the first element is
+     *  equal to the second element; and a positive number if the first
+     *  element is greater than the second element
+     */
+    protected int compareClass(Object element1, Object element2) {
+        return classComparison(element1) - classComparison(element2);
+    }
+
+    /**
+     * Returns a number reflecting the collation order of the given resources
+     * based on their resource names.
+     *
+     * @param resource1 the first resource element to be ordered
+     * @param resource2 the second resource element to be ordered
+     * @return a negative number if the first element is less  than the 
+     *  second element; the value <code>0</code> if the first element is
+     *  equal to the second element; and a positive number if the first
+     *  element is greater than the second element
+     */
+    protected int compareNames(IResource resource1, IResource resource2) {
+        return getComparator().compare(resource1.getName(), resource2.getName());
+    }
+
+    /**
+     * Returns a number reflecting the collation order of the given resources
+     * based on their respective file extensions. Resources with the same file
+     * extension will be collated based on their names.
+     *
+     * @param resource1 the first resource element to be ordered
+     * @param resource2 the second resource element to be ordered
+     * @return a negative number if the first element is less  than the 
+     *  second element; the value <code>0</code> if the first element is
+     *  equal to the second element; and a positive number if the first
+     *  element is greater than the second element
+     */
+    protected int compareTypes(IResource resource1, IResource resource2) {
+        String ext1 = getExtensionFor(resource1);
+        String ext2 = getExtensionFor(resource2);
+
+        // Compare extensions.  If they're different then return a value that
+        // indicates correct extension ordering.  If they're the same then
+        // return a value that indicates the correct NAME ordering.
+        int result = getComparator().compare(ext1, ext2);
+
+        if (result != 0) {
+			return result;
+		}
+
+        return compareNames(resource1, resource2);
+    }
+
+    /**
+     * Returns the sort criteria of this sorter.
+     *
+     * @return the sort criterion: one of <code>NAME</code> or <code>TYPE</code>
+     */
+    public int getCriteria() {
+        return criteria;
+    }
+
+    /**
+     * Returns the extension portion of the given resource.
+     *
+     * @param resource the resource
+     * @return the file extension, possibily the empty string
+     */
+    private String getExtensionFor(IResource resource) {
+        String ext = resource.getFileExtension();
+        return ext == null ? "" : ext; //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the sort criteria of this sorter.
+     * 
+     * @param criteria the sort criterion: 
+     *	one of <code>ResourceSorter.NAME</code> or 
+     *	<code>ResourceSorter.TYPE</code>
+     */
+    public void setCriteria(int criteria) {
+        this.criteria = criteria;
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigator.java
new file mode 100644
index 0000000..5c043c4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigator.java
@@ -0,0 +1,1580 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Benjamin Muskalla - bug 105041
+ *     Remy Chi Jian Suen - bug 144102
+ *******************************************************************************/
+
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.osgi.util.NLS;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.util.Util;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.OpenAndLinkWithEditorHelper;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ResourceWorkingSetFilter;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.OpenFileAction;
+import org.eclipse.ui.actions.OpenResourceAction;
+import org.eclipse.ui.handlers.CollapseAllHandler;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.ide.ResourceUtil;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.ISetSelectionTarget;
+import org.eclipse.ui.part.IShowInSource;
+import org.eclipse.ui.part.IShowInTarget;
+import org.eclipse.ui.part.PluginTransfer;
+import org.eclipse.ui.part.ResourceTransfer;
+import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.views.framelist.FrameList;
+import org.eclipse.ui.views.framelist.TreeFrame;
+
+/**
+ * Implements the Resource Navigator view.
+ */
+public class ResourceNavigator extends ViewPart implements ISetSelectionTarget,
+        IResourceNavigator {
+
+    private TreeViewer viewer;
+
+    private IDialogSettings settings;
+
+    private IMemento memento;
+
+    private FrameList frameList;
+
+    private ResourceNavigatorActionGroup actionGroup;
+
+    private ResourcePatternFilter patternFilter = new ResourcePatternFilter();
+
+    private ResourceWorkingSetFilter workingSetFilter = new ResourceWorkingSetFilter();
+
+    private boolean linkingEnabled;
+
+    private boolean dragDetected;
+
+    private Listener dragDetectListener;
+    /**
+     * Remembered working set.
+     */
+    private IWorkingSet workingSet;
+
+    /**
+	 * Marks whether the working set we're using is currently empty. In this
+	 * event we're effectively not using a working set.
+	 */
+    private boolean emptyWorkingSet = false;
+    
+    /**
+	 * Settings constant for section name (value <code>ResourceNavigator</code>).
+	 */
+    private static final String STORE_SECTION = "ResourceNavigator"; //$NON-NLS-1$
+
+    /**
+     * Settings constant for sort order (value <code>ResourceViewer.STORE_SORT_TYPE</code>).
+     */
+    private static final String STORE_SORT_TYPE = "ResourceViewer.STORE_SORT_TYPE"; //$NON-NLS-1$
+
+    /**
+     * Settings constant for working set (value <code>ResourceWorkingSetFilter.STORE_WORKING_SET</code>).
+     */
+    private static final String STORE_WORKING_SET = "ResourceWorkingSetFilter.STORE_WORKING_SET"; //$NON-NLS-1$
+
+    /**
+     * @deprecated No longer used but preserved to avoid an api change.
+     */
+    public static final String NAVIGATOR_VIEW_HELP_ID = INavigatorHelpContextIds.RESOURCE_VIEW;
+
+    /**
+     * True iff we've already scheduled an asynchronous call to linkToEditor
+     */
+    private boolean linkScheduled = false;
+    
+    // Persistance tags.
+    private static final String TAG_SORTER = "sorter"; //$NON-NLS-1$
+
+    private static final String TAG_FILTERS = "filters"; //$NON-NLS-1$
+
+    private static final String TAG_FILTER = "filter"; //$NON-NLS-1$
+
+    private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$
+
+    private static final String TAG_EXPANDED = "expanded"; //$NON-NLS-1$
+
+    private static final String TAG_ELEMENT = "element"; //$NON-NLS-1$
+
+    private static final String TAG_IS_ENABLED = "isEnabled"; //$NON-NLS-1$
+
+    private static final String TAG_PATH = "path"; //$NON-NLS-1$
+
+    private static final String TAG_CURRENT_FRAME = "currentFrame"; //$NON-NLS-1$
+
+    private IPartListener partListener = new IPartListener() {
+        public void partActivated(IWorkbenchPart part) {
+            if (part instanceof IEditorPart) {
+				editorActivated((IEditorPart) part);
+			}
+        }
+
+        public void partBroughtToTop(IWorkbenchPart part) {
+            if (part instanceof IEditorPart) {
+				editorActivated((IEditorPart) part);
+			}
+        }
+
+        public void partClosed(IWorkbenchPart part) {
+        }
+
+        public void partDeactivated(IWorkbenchPart part) {
+        }
+
+        public void partOpened(IWorkbenchPart part) {
+        }
+    };
+
+    private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
+        public void propertyChange(PropertyChangeEvent event) {
+            String property = event.getProperty();
+            Object newValue = event.getNewValue();
+            Object oldValue = event.getOldValue();
+           
+            if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)
+                    && oldValue == workingSet) {
+                setWorkingSet(null);
+            } else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE
+                    .equals(property)
+                    && newValue == workingSet) {
+                updateTitle();
+            } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE
+                    .equals(property)
+                    && newValue == workingSet) {
+				if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
+					// act as if the working set has been made null
+					if (!emptyWorkingSet) {
+						emptyWorkingSet = true;
+						workingSetFilter.setWorkingSet(null);
+					}
+				} else {
+					// we've gone from empty to non-empty on our set.
+					// Restore it.
+					if (emptyWorkingSet) {
+					    emptyWorkingSet = false;
+						workingSetFilter.setWorkingSet(workingSet);
+					}
+				}
+				getViewer().refresh();
+            }
+        }
+    };
+
+	private CollapseAllHandler collapseAllHandler;
+	
+	/**
+	 * Helper to open and activate editors.
+	 * 
+	 * @since 3.5
+	 */
+	private OpenAndLinkWithEditorHelper openAndLinkWithEditorHelper;
+
+
+    /**
+     * Constructs a new resource navigator view.
+     */
+    public ResourceNavigator() {
+        IDialogSettings viewsSettings = getPlugin().getDialogSettings();
+
+        settings = viewsSettings.getSection(STORE_SECTION);
+        if (settings == null) {
+            settings = viewsSettings.addNewSection(STORE_SECTION);
+        }
+
+        initLinkingEnabled();
+    }
+
+    /**
+     * Converts the given selection into a form usable by the viewer,
+     * where the elements are resources.
+     */
+    private StructuredSelection convertSelection(ISelection selection) {
+        ArrayList list = new ArrayList();
+        if (selection instanceof IStructuredSelection) {
+            IStructuredSelection ssel = (IStructuredSelection) selection;
+            for (Iterator i = ssel.iterator(); i.hasNext();) {
+                Object o = i.next();
+                IResource resource = null;
+                if (o instanceof IResource) {
+                    resource = (IResource) o;
+                } else {
+                    if (o instanceof IAdaptable) {
+                        resource = (IResource) ((IAdaptable) o)
+                                .getAdapter(IResource.class);
+                    }
+                }
+                if (resource != null) {
+                    list.add(resource);
+                }
+            }
+        }
+        return new StructuredSelection(list);
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IWorkbenchPart.
+     */
+    public void createPartControl(Composite parent) {
+        TreeViewer viewer = createViewer(parent);
+        this.viewer = viewer;
+
+        if (memento != null) {
+            restoreFilters();
+            restoreLinkingEnabled();
+        }
+        frameList = createFrameList();
+        initDragAndDrop();
+        updateTitle();
+
+//        initContextMenu();
+
+        initResourceComparator();
+        initWorkingSetFilter();
+
+        // make sure input is set after sorters and filters,
+        // to avoid unnecessary refreshes
+        viewer.setInput(getInitialInput());
+
+//        // make actions after setting input, because some actions
+//        // look at the viewer for enablement (e.g. the Up action)
+//        makeActions();
+//
+//        // Fill the action bars and update the global action handlers'
+//        // enabled state to match the current selection.
+//        getActionGroup().fillActionBars(getViewSite().getActionBars());
+//        updateActionBars((IStructuredSelection) viewer.getSelection());
+//
+//        getSite().setSelectionProvider(viewer);
+//        getSite().getPage().addPartListener(partListener);
+//        IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
+//                .getWorkingSetManager();
+//        workingSetManager.addPropertyChangeListener(propertyChangeListener);
+//
+//        if (memento != null) {
+//			restoreState(memento);
+//		}
+//        memento = null;
+//
+//        // Set help for the view
+//        getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(
+//				viewer.getControl(), getHelpContextId());
+    }
+
+    /**
+     * Returns the help context id to use for this view.
+     * 
+     * @since 2.0
+     */
+    protected String getHelpContextId() {
+        return INavigatorHelpContextIds.RESOURCE_VIEW;
+    }
+
+    /**
+     * Initializes and registers the context menu.
+     * 
+     * @since 2.0
+     */
+    protected void initContextMenu() {
+        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener() {
+            public void menuAboutToShow(IMenuManager manager) {
+                ResourceNavigator.this.fillContextMenu(manager);
+            }
+        });
+        TreeViewer viewer = getTreeViewer();
+        Menu menu = menuMgr.createContextMenu(viewer.getTree());
+        viewer.getTree().setMenu(menu);
+        getSite().registerContextMenu(menuMgr, viewer);
+    }
+
+    /**
+     * Creates the viewer.
+     * 
+     * @param parent the parent composite
+     * @since 2.0
+     */
+    protected TreeViewer createViewer(Composite parent) {
+        TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
+                | SWT.V_SCROLL);
+        viewer.setUseHashlookup(true);
+        initContentProvider(viewer);
+        initLabelProvider(viewer);
+        initFilters(viewer);
+        initListeners(viewer);
+
+        return viewer;
+    }
+
+    /**
+     * Sets the content provider for the viewer.
+     * 
+     * @param viewer the viewer
+     * @since 2.0
+     */
+    protected void initContentProvider(TreeViewer viewer) {
+        viewer.setContentProvider(new WorkbenchContentProvider());
+    }
+
+    /**
+     * Sets the label provider for the viewer.
+     * 
+     * @param viewer the viewer
+     * @since 2.0
+     */
+    protected void initLabelProvider(TreeViewer viewer) {
+        viewer.setLabelProvider(new DecoratingLabelProvider(
+                new WorkbenchLabelProvider(), getPlugin().getWorkbench()
+                        .getDecoratorManager().getLabelDecorator()));
+    }
+
+    /**
+     * Adds the filters to the viewer.
+     * 
+     * @param viewer the viewer
+     * @since 2.0
+     */
+    protected void initFilters(TreeViewer viewer) {
+        viewer.addFilter(patternFilter);
+        viewer.addFilter(workingSetFilter);
+    }
+
+    /**
+     * Initializes the linking enabled setting from the preference store.
+     */
+    private void initLinkingEnabled() {
+        // Try the dialog settings first, which remember the last choice.
+        String setting = settings
+                .get(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
+        if (setting != null) {
+            linkingEnabled = setting.equals("true"); //$NON-NLS-1$
+            return;
+        }
+        // If not in the dialog settings, check the preference store for the default setting.
+        // Use the UI plugin's preference store since this is a public preference.
+        linkingEnabled = PlatformUI.getPreferenceStore().getBoolean(
+                IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
+    }
+
+    /**
+     * Adds the listeners to the viewer.
+     * 
+     * @param viewer the viewer
+     * @since 2.0
+     */
+    protected void initListeners(final TreeViewer viewer) {
+        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                handleSelectionChanged(event);
+            }
+        });
+        viewer.addDoubleClickListener(new IDoubleClickListener() {
+            public void doubleClick(DoubleClickEvent event) {
+                handleDoubleClick(event);
+            }
+        });
+        
+		openAndLinkWithEditorHelper = new OpenAndLinkWithEditorHelper(viewer) {
+			protected void activate(ISelection selection) {
+				Object selectedElement = getSingleElement(selection);
+				if (selectedElement instanceof IFile) {
+					IEditorInput input = new FileEditorInput((IFile)selectedElement);
+					final IWorkbenchPage page = getSite().getPage();
+					IEditorPart editor = page.findEditor(input);
+					if (editor != null) {
+						page.activate(editor);
+					}
+				}
+				
+			}
+
+			protected void linkToEditor(ISelection selection) {
+		        if (!linkScheduled) {
+					// Ensure that if another selection change arrives while we're waiting for the *syncExec,
+					// we only do this work once.
+					linkScheduled = true;
+					getSite().getShell().getDisplay().asyncExec(new Runnable() {
+						public void run() {
+							// There's no telling what might have changed since the syncExec was scheduled.
+							// Check to make sure that the widgets haven't been disposed.
+							linkScheduled = false;
+
+							if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed()) {
+								return;
+							}
+
+							if (dragDetected == false) {
+								// only synchronize with editor when the selection is not the result
+								// of a drag. Fixes bug 22274.
+								ResourceNavigator.this.linkToEditor(viewer.getSelection());
+							}
+						}
+					});
+				}
+			}
+
+			protected void open(ISelection selection, boolean activate) {
+				handleOpen(selection);
+			}
+
+		};
+        
+
+        viewer.getControl().addKeyListener(new KeyListener() {
+            public void keyPressed(KeyEvent event) {
+                handleKeyPressed(event);
+            }
+
+            public void keyReleased(KeyEvent event) {
+                handleKeyReleased(event);
+            }
+        });
+        
+        openAndLinkWithEditorHelper.setLinkWithEditor(linkingEnabled);
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IWorkbenchPart.
+     */
+    public void dispose() {
+        getSite().getPage().removePartListener(partListener);
+
+        IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
+                .getWorkingSetManager();
+        workingSetManager.removePropertyChangeListener(propertyChangeListener);
+
+        if (collapseAllHandler != null) {
+			collapseAllHandler.dispose();
+		}
+        
+        if (getActionGroup() != null) {
+            getActionGroup().dispose();
+        }
+        Control control = viewer.getControl();
+        if (dragDetectListener != null && control != null
+                && control.isDisposed() == false) {
+            control.removeListener(SWT.DragDetect, dragDetectListener);
+        }
+        
+        super.dispose();
+    }
+
+    /**
+     * An editor has been activated.  Sets the selection in this navigator
+     * to be the editor's input, if linking is enabled.
+     * 
+     * @param editor the active editor
+     * @since 2.0
+     */
+    protected void editorActivated(IEditorPart editor) {
+        if (!isLinkingEnabled()) {
+            return;
+        }
+
+        IFile file = ResourceUtil.getFile(editor.getEditorInput());
+        if (file != null) {
+            ISelection newSelection = new StructuredSelection(file);
+            if (getTreeViewer().getSelection().equals(newSelection)) {
+                getTreeViewer().getTree().showSelection();
+            } else {
+                getTreeViewer().setSelection(newSelection, true);
+            }
+        }
+    }
+
+    /**
+     * Called when the context menu is about to open.
+     * Delegates to the action group using the viewer's selection as the action context.
+     * @since 2.0
+     */
+    protected void fillContextMenu(IMenuManager menu) {
+        IStructuredSelection selection = (IStructuredSelection) getViewer()
+                .getSelection();
+        getActionGroup().setContext(new ActionContext(selection));
+        getActionGroup().fillContextMenu(menu);
+    }
+
+    /*
+     * @see IResourceNavigatorPart
+     * @since 2.0
+     */
+    public FrameList getFrameList() {
+        return frameList;
+    }
+
+    /**
+     * Returns the initial input for the viewer.
+     * Tries to convert the page input to a resource, either directly or via IAdaptable.
+     * If the resource is a container, it uses that.
+     * If the resource is a file, it uses its parent folder.
+     * If a resource could not be obtained, it uses the workspace root.
+     * 
+     * @since 2.0
+     */
+    protected IAdaptable getInitialInput() {
+        IAdaptable input = getSite().getPage().getInput();
+        if (input != null) {
+            IResource resource = null;
+            if (input instanceof IResource) {
+                resource = (IResource) input;
+            } else {
+                resource = (IResource) input.getAdapter(IResource.class);
+            }
+            if (resource != null) {
+                switch (resource.getType()) {
+                case IResource.FILE:
+                    return resource.getParent();
+                case IResource.FOLDER:
+                case IResource.PROJECT:
+                case IResource.ROOT:
+                    return resource;
+                default:
+                    // Unknown resource type.  Fall through.
+                    break;
+                }
+            }
+        }
+        return ResourcesPlugin.getWorkspace().getRoot();
+    }
+
+    /**
+     * Returns the pattern filter for this view.
+     *
+     * @return the pattern filter
+     * @since 2.0
+     */
+    public ResourcePatternFilter getPatternFilter() {
+        return this.patternFilter;
+    }
+
+    /**
+     * Returns the working set for this view.
+     *
+     * @return the working set
+     * @since 2.0
+     */
+    public IWorkingSet getWorkingSet() {
+        return workingSetFilter.getWorkingSet();
+    }
+
+    /**
+     * Returns the navigator's plugin.
+     * @return the UI plugin for this bundle
+     */
+    public AbstractUIPlugin getPlugin() {
+        return IDEWorkbenchPlugin.getDefault();
+    }
+
+    /**
+	 * Return the sorter. If a comparator was set using
+	 * {@link #setComparator(ResourceComparator)}, this method will return
+	 * <code>null</code>.
+	 * 
+	 * @since 2.0
+	 * @deprecated as of 3.3, use {@link ResourceNavigator#getComparator()}
+	 */
+    public ResourceSorter getSorter() {
+        ViewerSorter sorter = getTreeViewer().getSorter();
+        if (sorter instanceof ResourceSorter) {
+        	return (ResourceSorter) sorter;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the comparator.  If a sorter was set using
+	 * {@link #setSorter(ResourceSorter)}, this method will return
+	 * <code>null</code>.
+     * 
+     * @return the <code>ResourceComparator</code>
+     * @since 3.3
+     */
+
+    public ResourceComparator getComparator(){
+    	ViewerComparator comparator = getTreeViewer().getComparator();
+    	if (comparator instanceof ResourceComparator) {
+    		return (ResourceComparator) comparator;
+    	}
+    	return null;
+    }
+    /**
+     * Returns the resource viewer which shows the resource hierarchy.
+     * @since 2.0
+     */
+    public TreeViewer getViewer() {
+        return viewer;
+    }
+
+    /**
+     * Returns the tree viewer which shows the resource hierarchy.
+     * @return the tree viewer
+     * @since 2.0
+     */
+    public TreeViewer getTreeViewer() {
+        return viewer;
+    }
+
+    /**
+     * Returns the shell to use for opening dialogs.
+     * Used in this class, and in the actions.
+     * 
+     * @return the shell
+     * @deprecated use getViewSite().getShell()
+     */
+    public Shell getShell() {
+        return getViewSite().getShell();
+    }
+
+    /**
+     * Returns the message to show in the status line.
+     *
+     * @param selection the current selection
+     * @return the status line message
+     * @since 2.0
+     */
+    protected String getStatusLineMessage(IStructuredSelection selection) {
+        if (selection.size() == 1) {
+            Object o = selection.getFirstElement();
+            if (o instanceof IResource) {
+                return ((IResource) o).getFullPath().makeRelative().toString();
+            }
+            return ResourceNavigatorMessages.ResourceNavigator_oneItemSelected;
+        }
+        if (selection.size() > 1) {
+            return NLS.bind(ResourceNavigatorMessages.ResourceNavigator_statusLine, String.valueOf(selection.size()));
+        }
+        return ""; //$NON-NLS-1$
+    }
+
+    /**
+     * Returns the name for the given element.
+     * Used as the name for the current frame.
+     */
+    String getFrameName(Object element) {
+        if (element instanceof IResource) {
+			return ((IResource) element).getName();
+		}
+        String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
+        .getText(element);
+        if(text == null) {
+			return "";//$NON-NLS-1$
+		}
+        return text;
+    }
+
+    /**
+     * Returns the tool tip text for the given element.
+     * Used as the tool tip text for the current frame, and for the view title tooltip.
+     */
+    String getFrameToolTipText(Object element) {
+        if (element instanceof IResource) {
+            IPath path = ((IResource) element).getFullPath();
+            if (path.isRoot()) {
+				return ResourceNavigatorMessages.ResourceManager_toolTip;
+			}
+            return path.makeRelative().toString();
+        }
+        
+        String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
+        	.getText(element);
+        if(text == null) {
+			return "";//$NON-NLS-1$
+		}
+        return text;
+    }
+
+	/**
+	 * Handles an open event from the viewer. Opens an editor on the selected file.
+	 * 
+	 * @param event the open event
+	 * @since 2.0
+	 * @deprecated As of 3.5, replaced by {@link #handleOpen(ISelection)}
+	 */
+    protected void handleOpen(OpenEvent event) {
+        handleOpen(event.getSelection());
+	}
+
+	/**
+	 * Handles an open event from the viewer. Opens an editor on the selected file.
+	 * 
+	 * @param selection the selection
+	 * @since 3.5
+	 */
+	protected void handleOpen(ISelection selection) {
+		if (selection instanceof IStructuredSelection) {
+			OpenFileAction ofa = new OpenFileAction(getSite().getPage());
+			ofa.selectionChanged((IStructuredSelection) selection);
+			ofa.run();
+			//getActionGroup().runDefaultAction((IStructuredSelection)selection);
+		}
+    }
+
+    /**
+     * Handles a double-click event from the viewer.
+     * Expands or collapses a folder when double-clicked.
+     * 
+     * @param event the double-click event
+     * @since 2.0
+     */
+    protected void handleDoubleClick(DoubleClickEvent event) {
+        IStructuredSelection selection = (IStructuredSelection) event
+                .getSelection();
+        Object element = selection.getFirstElement();
+
+        // 1GBZIA0: ITPUI:WIN2000 - Double-clicking in navigator should expand/collapse containers
+        TreeViewer viewer = getTreeViewer();
+        if (viewer.isExpandable(element)) {
+            viewer.setExpandedState(element, !viewer.getExpandedState(element));
+		} else if (selection.size() == 1 && (element instanceof IResource)
+				&& ((IResource) element).getType() == IResource.PROJECT) {
+			OpenResourceAction ora = new OpenResourceAction(getSite());
+			ora.selectionChanged((IStructuredSelection) viewer.getSelection());
+			if (ora.isEnabled()) {
+				ora.run();
+			}
+		}
+
+    }
+
+    /**
+     * Handles a selection changed event from the viewer.
+     * Updates the status line and the action bars, and links to editor (if option enabled).
+     * 
+     * @param event the selection event
+     * @since 2.0
+     */
+    protected void handleSelectionChanged(SelectionChangedEvent event) {
+        final IStructuredSelection sel = (IStructuredSelection) event
+                .getSelection();
+        updateStatusLine(sel);
+        updateActionBars(sel);
+        dragDetected = false;
+    }
+
+    /**
+     * Handles a key press event from the viewer.
+     * Delegates to the action group.
+     * 
+     * @param event the key event
+     * @since 2.0
+     */
+    protected void handleKeyPressed(KeyEvent event) {
+        getActionGroup().handleKeyPressed(event);
+    }
+
+    /**
+     * Handles a key release in the viewer.  Does nothing by default.
+     * 
+     * @param event the key event
+     * @since 2.0
+     */
+    protected void handleKeyReleased(KeyEvent event) {
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IViewPart.
+     */
+    public void init(IViewSite site, IMemento memento) throws PartInitException {
+        super.init(site, memento);
+        this.memento = memento;
+    }
+
+    /**
+     * Adds drag and drop support to the navigator.
+     * 
+     * @since 2.0
+     */
+    protected void initDragAndDrop() {
+        int ops = DND.DROP_COPY | DND.DROP_MOVE;
+        Transfer[] transfers = new Transfer[] {
+                LocalSelectionTransfer.getInstance(),
+                ResourceTransfer.getInstance(), FileTransfer.getInstance(),
+                PluginTransfer.getInstance() };
+        TreeViewer viewer = getTreeViewer();
+        viewer.addDragSupport(ops, transfers, new NavigatorDragAdapter(viewer));
+        NavigatorDropAdapter adapter = new NavigatorDropAdapter(viewer);
+        adapter.setFeedbackEnabled(false);
+        viewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, adapter);
+        dragDetectListener = new Listener() {
+            public void handleEvent(Event event) {
+                dragDetected = true;
+            }
+        };
+        viewer.getControl().addListener(SWT.DragDetect, dragDetectListener);
+    }
+
+    /**
+     * Creates the frame source and frame list, and connects them.
+     * 
+     * @since 2.0
+     */
+    protected FrameList createFrameList() {
+        NavigatorFrameSource frameSource = new NavigatorFrameSource(this);
+        FrameList frameList = new FrameList(frameSource);
+        frameSource.connectTo(frameList);
+        return frameList;
+    }
+
+    /**
+     * Initializes the sorter.
+     * 
+     * @deprecated as of 3.3, use {@link ResourceNavigator#initResourceComparator()} instead
+     */
+    protected void initResourceSorter() {
+        int sortType = ResourceSorter.NAME;
+        try {
+            int sortInt = 0;
+            if (memento != null) {
+                String sortStr = memento.getString(TAG_SORTER);
+                if (sortStr != null) {
+					sortInt = new Integer(sortStr).intValue();
+				}
+            } else {
+                sortInt = settings.getInt(STORE_SORT_TYPE);
+            }
+            if (sortInt == ResourceSorter.NAME
+                    || sortInt == ResourceSorter.TYPE) {
+				sortType = sortInt;
+			}
+        } catch (NumberFormatException e) {
+        }
+        setSorter(new ResourceSorter(sortType));
+    }
+    
+    /**
+     * Initializes the comparator.
+	 * @since 3.3
+     */
+    protected void initResourceComparator(){
+        int sortType = ResourceComparator.NAME;
+        try {
+            int sortInt = 0;
+            if (memento != null) {
+                String sortStr = memento.getString(TAG_SORTER);
+                if (sortStr != null) {
+					sortInt = new Integer(sortStr).intValue();
+				}
+            } else {
+                sortInt = settings.getInt(STORE_SORT_TYPE);
+            }
+            if (sortInt == ResourceComparator.NAME
+                    || sortInt == ResourceComparator.TYPE) {
+				sortType = sortInt;
+			}
+        } catch (NumberFormatException e) {
+        }
+        setComparator(new ResourceComparator(sortType));
+    }
+
+    /**
+     * Restores the working set filter from the persistence store.
+     */
+    protected void initWorkingSetFilter() {
+        String workingSetName = settings.get(STORE_WORKING_SET);
+
+        IWorkingSet workingSet = null;
+        
+        if (workingSetName != null && workingSetName.equals("") == false) { //$NON-NLS-1$
+			IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
+					.getWorkingSetManager();
+			workingSet = workingSetManager.getWorkingSet(workingSetName);
+		} else if (PlatformUI
+				.getPreferenceStore()
+				.getBoolean(
+						IWorkbenchPreferenceConstants.USE_WINDOW_WORKING_SET_BY_DEFAULT)) {
+			// use the window set by default if the global preference is set
+			workingSet = getSite().getPage().getAggregateWorkingSet();
+		}
+
+		if (workingSet != null) {
+			// Only initialize filter. Don't set working set into viewer.
+			// Working set is set via WorkingSetFilterActionGroup
+			// during action creation.
+			workingSetFilter.setWorkingSet(workingSet);
+			internalSetWorkingSet(workingSet);
+		}
+    }
+
+    /**
+	 * Returns whether the navigator selection automatically tracks the active
+	 * editor.
+	 * 
+	 * @return <code>true</code> if linking is enabled, <code>false</code>
+	 *         if not
+	 * @since 2.0 (this was protected in 2.0, but was made public in 2.1)
+	 */
+    public boolean isLinkingEnabled() {
+        return linkingEnabled;
+    }
+
+	/**
+	 * Brings the corresponding editor to top if the selected resource is open.
+	 * 
+	 * @since 2.0
+	 * @deprecated As of 3.5, replaced by {@link #linkToEditor(ISelection)}
+	 */
+    protected void linkToEditor(IStructuredSelection selection) {
+    	linkToEditor((ISelection)selection);
+	}
+
+	/**
+	 * Brings the corresponding editor to top if the selected resource is open.
+	 * 
+	 * @since 3.5
+	 */
+	protected void linkToEditor(ISelection selection) {
+
+    	if (this != this.getSite().getPage().getActivePart())
+    		return;
+    	
+        Object obj = getSingleElement(selection);
+		if (obj instanceof IFile) {
+            IFile file = (IFile) obj;
+            IWorkbenchPage page = getSite().getPage();
+            IEditorPart editor = ResourceUtil.findEditor(page, file);
+            if (editor != null) {
+                page.bringToTop(editor);
+                return;
+            }
+        }
+    }
+
+    /**
+     * Creates the action group, which encapsulates all actions for the view.
+     */
+    protected void makeActions() {
+    	MainActionGroup group = new MainActionGroup(this);
+        setActionGroup(group);
+        
+        IHandlerService service = (IHandlerService) getSite().getService(IHandlerService.class);
+    	service.activateHandler("org.eclipse.ui.navigate.linkWithEditor", //$NON-NLS-1$
+    			new ActionHandler(group.toggleLinkingAction));
+    	collapseAllHandler = new CollapseAllHandler(viewer);
+    	service.activateHandler(CollapseAllHandler.COMMAND_ID,
+				collapseAllHandler);
+    }
+
+    /**
+     * Restores the saved filter settings.
+     */
+    private void restoreFilters() {
+        IMemento filtersMem = memento.getChild(TAG_FILTERS);
+
+        if (filtersMem != null) { //filters have been defined
+            IMemento children[] = filtersMem.getChildren(TAG_FILTER);
+
+            // check if first element has new tag defined, indicates new version
+            if (children.length > 0
+                    && children[0].getString(TAG_IS_ENABLED) != null) {
+                ArrayList selectedFilters = new ArrayList();
+                ArrayList unSelectedFilters = new ArrayList();
+                for (int i = 0; i < children.length; i++) {
+                    if (children[i].getString(TAG_IS_ENABLED).equals(
+                            String.valueOf(true))) {
+						selectedFilters.add(children[i].getString(TAG_ELEMENT));
+					} else {
+						//enabled == false
+                        unSelectedFilters.add(children[i]
+                                .getString(TAG_ELEMENT));
+					}
+                }
+
+                /* merge filters from Memento with selected = true filters from plugins
+                 * ensure there are no duplicates & don't override user preferences	 */
+                List pluginFilters = FiltersContentProvider.getDefaultFilters();
+                for (Iterator iter = pluginFilters.iterator(); iter.hasNext();) {
+                    String element = (String) iter.next();
+                    if (!selectedFilters.contains(element)
+                            && !unSelectedFilters.contains(element)) {
+						selectedFilters.add(element);
+					}
+                }
+
+                //Convert to an array of Strings
+                String[] patternArray = new String[selectedFilters.size()];
+                selectedFilters.toArray(patternArray);
+                getPatternFilter().setPatterns(patternArray);
+
+            } else { //filters defined, old version: ignore filters from plugins
+                String filters[] = new String[children.length];
+                for (int i = 0; i < children.length; i++) {
+                    filters[i] = children[i].getString(TAG_ELEMENT);
+                }
+                getPatternFilter().setPatterns(filters);
+            }
+        } else { //no filters defined, old version: ignore filters from plugins
+            getPatternFilter().setPatterns(new String[0]);
+        }
+    }
+
+    /**
+     * Restores the state of the receiver to the state described in the specified memento.
+     *
+     * @param memento the memento
+     * @since 2.0
+     */
+    protected void restoreState(IMemento memento) {
+        TreeViewer viewer = getTreeViewer();
+        IMemento frameMemento = memento.getChild(TAG_CURRENT_FRAME);
+
+        if (frameMemento != null) {
+            TreeFrame frame = new TreeFrame(viewer);
+            frame.restoreState(frameMemento);
+            frame.setName(getFrameName(frame.getInput()));
+            frame.setToolTipText(getFrameToolTipText(frame.getInput()));
+            viewer.setSelection(new StructuredSelection(frame.getInput()));
+            frameList.gotoFrame(frame);
+        } else {
+            IContainer container = ResourcesPlugin.getWorkspace().getRoot();
+            IMemento childMem = memento.getChild(TAG_EXPANDED);
+            if (childMem != null) {
+                ArrayList elements = new ArrayList();
+                IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
+                for (int i = 0; i < elementMem.length; i++) {
+                    Object element = container.findMember(elementMem[i]
+                            .getString(TAG_PATH));
+                    if (element != null) {
+                        elements.add(element);
+                    }
+                }
+                viewer.setExpandedElements(elements.toArray());
+            }
+            childMem = memento.getChild(TAG_SELECTION);
+            if (childMem != null) {
+                ArrayList list = new ArrayList();
+                IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
+                for (int i = 0; i < elementMem.length; i++) {
+                    Object element = container.findMember(elementMem[i]
+                            .getString(TAG_PATH));
+                    if (element != null) {
+                        list.add(element);
+                    }
+                }
+                viewer.setSelection(new StructuredSelection(list));
+            }
+        }
+    }
+
+    /**
+     * Restores the linking enabled state.
+     */
+    private void restoreLinkingEnabled() {
+        Integer val = memento
+                .getInteger(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
+        if (val != null) {
+            linkingEnabled = val.intValue() != 0;
+        }
+    }
+
+    /**
+     * @see ViewPart#saveState
+     */
+    public void saveState(IMemento memento) {
+        TreeViewer viewer = getTreeViewer();
+        if (viewer == null) {
+            if (this.memento != null) {
+				memento.putMemento(this.memento);
+			}
+            return;
+        }
+
+        //save sorter
+        if (getComparator() != null) {
+        	memento.putInteger(TAG_SORTER, getComparator().getCriteria());
+        } else if (getSorter() != null) {
+        	memento.putInteger(TAG_SORTER, getSorter().getCriteria());
+        }
+
+        //save filters
+        String filters[] = getPatternFilter().getPatterns();
+        List selectedFilters = Arrays.asList(filters);
+        List allFilters = FiltersContentProvider.getDefinedFilters();
+        IMemento filtersMem = memento.createChild(TAG_FILTERS);
+        for (Iterator iter = allFilters.iterator(); iter.hasNext();) {
+            String element = (String) iter.next();
+            IMemento child = filtersMem.createChild(TAG_FILTER);
+            child.putString(TAG_ELEMENT, element);
+            child.putString(TAG_IS_ENABLED, String.valueOf(selectedFilters
+                    .contains(element)));
+        }
+
+        if (frameList.getCurrentIndex() > 0) {
+            //save frame, it's not the "home"/workspace frame
+            TreeFrame currentFrame = (TreeFrame) frameList.getCurrentFrame();
+            IMemento frameMemento = memento.createChild(TAG_CURRENT_FRAME);
+            currentFrame.saveState(frameMemento);
+        } else {
+            //save visible expanded elements
+            Object expandedElements[] = viewer.getVisibleExpandedElements();
+            if (expandedElements.length > 0) {
+                IMemento expandedMem = memento.createChild(TAG_EXPANDED);
+                for (int i = 0; i < expandedElements.length; i++) {
+                    if (expandedElements[i] instanceof IResource) {
+                        IMemento elementMem = expandedMem
+                                .createChild(TAG_ELEMENT);
+                        elementMem.putString(TAG_PATH,
+                                ((IResource) expandedElements[i]).getFullPath()
+                                        .toString());
+                    }
+                }
+            }
+            //save selection
+            Object elements[] = ((IStructuredSelection) viewer.getSelection())
+                    .toArray();
+            if (elements.length > 0) {
+                IMemento selectionMem = memento.createChild(TAG_SELECTION);
+                for (int i = 0; i < elements.length; i++) {
+                    if (elements[i] instanceof IResource) {
+                        IMemento elementMem = selectionMem
+                                .createChild(TAG_ELEMENT);
+                        elementMem.putString(TAG_PATH,
+                                ((IResource) elements[i]).getFullPath()
+                                        .toString());
+                    }
+                }
+            }
+        }
+
+        saveLinkingEnabled(memento);
+    }
+
+    /**
+     * Saves the linking enabled state.
+     */
+    private void saveLinkingEnabled(IMemento memento) {
+        memento.putInteger(
+                IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
+                linkingEnabled ? 1 : 0);
+    }
+
+    /**
+     * Selects and reveals the specified elements.
+     */
+    public void selectReveal(ISelection selection) {
+        StructuredSelection ssel = convertSelection(selection);
+        if (!ssel.isEmpty()) {
+            getViewer().getControl().setRedraw(false);
+            getViewer().setSelection(ssel, true);
+            getViewer().getControl().setRedraw(true);
+        }
+    }
+
+    /**
+     * Saves the filters defined as strings in <code>patterns</code>
+     * in the preference store.
+     */
+    public void setFiltersPreference(String[] patterns) {
+
+        StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < patterns.length; i++) {
+            if (i != 0) {
+				sb.append(ResourcePatternFilter.COMMA_SEPARATOR);
+			}
+            sb.append(patterns[i]);
+        }
+
+        getPlugin().getPreferenceStore().setValue(
+                ResourcePatternFilter.FILTERS_TAG, sb.toString());
+
+        // remove value in old workbench preference store location
+        IPreferenceStore preferenceStore = IDEWorkbenchPlugin.getDefault()
+                .getPreferenceStore();
+        String storedPatterns = preferenceStore
+                .getString(ResourcePatternFilter.FILTERS_TAG);
+        if (storedPatterns.length() > 0) {
+			preferenceStore.setValue(ResourcePatternFilter.FILTERS_TAG, ""); //$NON-NLS-1$
+		}
+    }
+
+    /**
+     * @see IWorkbenchPart#setFocus()
+     */
+    public void setFocus() {
+        getTreeViewer().getTree().setFocus();
+    }
+
+    /**
+     * Note: For experimental use only.
+     * Sets the decorator for the navigator.
+     * <p>
+     * As of 2.0, this method no longer has any effect.
+     * </p>
+     *
+     * @param decorator a label decorator or <code>null</code> for no decorations.
+     * @deprecated use the decorators extension point instead; see IWorkbench.getDecoratorManager()
+     */
+    public void setLabelDecorator(ILabelDecorator decorator) {
+        // do nothing
+    }
+
+    /**
+     * @see IResourceNavigator#setLinkingEnabled(boolean)
+     * @since 2.1
+     */
+    public void setLinkingEnabled(boolean enabled) {
+        this.linkingEnabled = enabled;
+
+        // remember the last setting in the dialog settings
+        settings.put(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
+                enabled);
+
+        // if turning linking on, update the selection to correspond to the active editor
+        if (enabled) {
+            IEditorPart editor = getSite().getPage().getActiveEditor();
+            if (editor != null) {
+                editorActivated(editor);
+            }
+        }
+        openAndLinkWithEditorHelper.setLinkWithEditor(enabled);
+    }
+
+    /**
+     * Sets the resource sorter.
+     * 
+     * @param sorter the resource sorter
+     * @since 2.0
+     * @deprecated as of 3.3, use {@link ResourceNavigator#setComparator(ResourceComparator)}
+     */
+    public void setSorter(ResourceSorter sorter) {
+        TreeViewer viewer = getTreeViewer();
+        ViewerSorter viewerSorter = viewer.getSorter();
+
+        viewer.getControl().setRedraw(false);
+        if (viewerSorter == sorter) {
+            viewer.refresh();
+        } else {
+            viewer.setSorter(sorter);
+        }
+        viewer.getControl().setRedraw(true);
+        settings.put(STORE_SORT_TYPE, sorter.getCriteria());
+
+        // update the sort actions' checked state
+        updateActionBars((IStructuredSelection) viewer.getSelection());
+    }
+    
+    /**
+     * Sets the resource comparator
+     * 
+     * @param comparator the resource comparator
+     * @since 3.3
+     */
+    public void setComparator(ResourceComparator comparator){
+        TreeViewer viewer = getTreeViewer();
+        ViewerComparator viewerComparator = viewer.getComparator();
+
+        viewer.getControl().setRedraw(false);
+        if (viewerComparator == comparator) {
+            viewer.refresh();
+        } else {
+            viewer.setComparator(comparator);
+        }
+        viewer.getControl().setRedraw(true);
+        settings.put(STORE_SORT_TYPE, comparator.getCriteria());
+
+        // update the sort actions' checked state
+        updateActionBars((IStructuredSelection) viewer.getSelection());
+    }
+
+    /*
+     * @see org.eclipse.ui.views.navigator.IResourceNavigatorPart#setWorkingSet(IWorkingSet)
+     * @since 2.0
+     */
+    public void setWorkingSet(IWorkingSet workingSet) {
+        TreeViewer treeViewer = getTreeViewer();
+        Object[] expanded = treeViewer.getExpandedElements();
+        ISelection selection = treeViewer.getSelection();
+        
+        boolean refreshNeeded = internalSetWorkingSet(workingSet);
+        
+        workingSetFilter.setWorkingSet(emptyWorkingSet ? null : workingSet);
+        if (workingSet != null) {
+            settings.put(STORE_WORKING_SET, workingSet.getName());
+        } else {
+            settings.put(STORE_WORKING_SET, ""); //$NON-NLS-1$
+        }
+        updateTitle();
+        if(refreshNeeded) {
+        	treeViewer.refresh();
+        }
+        treeViewer.setExpandedElements(expanded);
+        if (selection.isEmpty() == false
+                && selection instanceof IStructuredSelection) {
+            IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+            treeViewer.reveal(structuredSelection.getFirstElement());
+        }
+    }
+
+	/**
+	 * Set the internal working set fields specific to the navigator.
+	 * 
+	 * @param workingSet
+	 *            the new working set
+	 * @since 3.2
+	 */
+	private boolean internalSetWorkingSet(IWorkingSet workingSet) {
+		boolean refreshNeeded = !Util.equals(this.workingSet, workingSet);
+		this.workingSet = workingSet;
+		emptyWorkingSet = workingSet != null && workingSet.isAggregateWorkingSet()
+				&& workingSet.isEmpty();
+		return refreshNeeded;
+	}
+
+    /**
+     * Updates the action bar actions.
+     * 
+     * @param selection the current selection
+     * @since 2.0
+     */
+    protected void updateActionBars(IStructuredSelection selection) {
+        ResourceNavigatorActionGroup group = getActionGroup();
+        if (group != null) {
+            group.setContext(new ActionContext(selection));
+            group.updateActionBars();
+        }
+    }
+
+    /**
+     * Updates the message shown in the status line.
+     *
+     * @param selection the current selection
+     */
+    protected void updateStatusLine(IStructuredSelection selection) {
+        String msg = getStatusLineMessage(selection);
+        //getViewSite().getActionBars().getStatusLineManager().setMessage(msg);
+    }
+
+    /**
+     * Updates the title text and title tool tip.
+     * Called whenever the input of the viewer changes.
+     * Called whenever the input of the viewer changes.
+     * 
+     * @since 2.0
+     */
+    public void updateTitle() {
+        Object input = getViewer().getInput();
+        IWorkspace workspace = ResourcesPlugin.getWorkspace();
+        IWorkingSet workingSet = workingSetFilter.getWorkingSet();
+
+        if (input == null || input.equals(workspace)
+                || input.equals(workspace.getRoot())) {
+            setContentDescription(""); //$NON-NLS-1$
+            if (workingSet != null) {
+                setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetToolTip, workingSet.getLabel()));
+            } else {
+                setTitleToolTip(""); //$NON-NLS-1$
+            }
+        } else {
+            ILabelProvider labelProvider = (ILabelProvider) getTreeViewer()
+                    .getLabelProvider();
+            String inputToolTip = getFrameToolTipText(input);
+            String text = labelProvider.getText(input);
+            if(text != null) {
+				setContentDescription(text);
+			}
+            if (workingSet != null) {
+                setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetInputToolTip, inputToolTip, workingSet.getLabel()));
+            } else {
+                setTitleToolTip(inputToolTip);
+            }
+        }
+    }
+
+    /**
+     * Returns the action group.
+     * 
+     * @return the action group
+     */
+    protected ResourceNavigatorActionGroup getActionGroup() {
+        return actionGroup;
+    }
+
+    /**
+     * Sets the action group.
+     * 
+     * @param actionGroup the action group
+     */
+    protected void setActionGroup(ResourceNavigatorActionGroup actionGroup) {
+        this.actionGroup = actionGroup;
+    }
+
+    /*
+     * @see IWorkbenchPart#getAdapter(Class)
+     */
+    public Object getAdapter(Class adapter) {
+        if (adapter == IShowInSource.class) {
+            return getShowInSource();
+        }
+        if (adapter == IShowInTarget.class) {
+            return getShowInTarget();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the <code>IShowInSource</code> for this view.
+     */
+    protected IShowInSource getShowInSource() {
+        return new IShowInSource() {
+            public ShowInContext getShowInContext() {
+                return new ShowInContext(getViewer().getInput(), getViewer()
+                        .getSelection());
+            }
+        };
+    }
+
+    /**
+     * Returns the <code>IShowInTarget</code> for this view.
+     */
+    protected IShowInTarget getShowInTarget() {
+        return new IShowInTarget() {
+            public boolean show(ShowInContext context) {
+                ArrayList toSelect = new ArrayList();
+                ISelection sel = context.getSelection();
+                if (sel instanceof IStructuredSelection) {
+                    IStructuredSelection ssel = (IStructuredSelection) sel;
+                    for (Iterator i = ssel.iterator(); i.hasNext();) {
+                        Object o = i.next();
+                        if (o instanceof IResource) {
+                            toSelect.add(o);
+                        } else if (o instanceof IMarker) {
+                            IResource r = ((IMarker) o).getResource();
+                            if (r.getType() != IResource.ROOT) {
+                                toSelect.add(r);
+                            }
+                        } else if (o instanceof IAdaptable) {
+                            IAdaptable adaptable = (IAdaptable) o;
+                            o = adaptable.getAdapter(IResource.class);
+                            if (o instanceof IResource) {
+                                toSelect.add(o);
+                            } else {
+                                o = adaptable.getAdapter(IMarker.class);
+                                if (o instanceof IMarker) {
+                                    IResource r = ((IMarker) o).getResource();
+                                    if (r.getType() != IResource.ROOT) {
+                                        toSelect.add(r);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                if (toSelect.isEmpty()) {
+                    Object input = context.getInput();
+                    if (input instanceof IAdaptable) {
+                        IAdaptable adaptable = (IAdaptable) input;
+                        Object o = adaptable.getAdapter(IResource.class);
+                        if (o instanceof IResource) {
+                            toSelect.add(o);
+                        }
+                    }
+                }
+                if (!toSelect.isEmpty()) {
+                    selectReveal(new StructuredSelection(toSelect));
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+    
+	/**
+	 * Returns the selected element if the selection consists of a single element only.
+	 * 
+	 * @param s the selection
+	 * @return the selected first element or null
+	 * @since 3.5
+	 */
+	protected static final Object getSingleElement(ISelection s) {
+		if (!(s instanceof IStructuredSelection))
+			return null;
+
+		IStructuredSelection selection = (IStructuredSelection)s;
+		if (selection.size() != 1)
+			return null;
+
+		return selection.getFirstElement();
+	}
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorAction.java
new file mode 100644
index 0000000..7cb7482
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorAction.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.SelectionProviderAction;
+
+/**
+ * Superclass of all actions provided by the resource navigator.
+ */
+public abstract class ResourceNavigatorAction extends SelectionProviderAction {
+
+    private IResourceNavigator navigator;
+
+    /**
+     * Creates a new instance of the class.
+     */
+    public ResourceNavigatorAction(IResourceNavigator navigator, String label) {
+        super(navigator.getViewer(), label);
+        this.navigator = navigator;
+    }
+
+    /**
+     * Returns the resource navigator for which this action was created.
+     */
+    public IResourceNavigator getNavigator() {
+        return navigator;
+    }
+
+    /**
+     * Returns the resource viewer
+     */
+    protected Viewer getViewer() {
+        return getNavigator().getViewer();
+    }
+
+    /**
+     * Returns the shell to use within actions.
+     */
+    protected Shell getShell() {
+        return getNavigator().getSite().getShell();
+    }
+
+    /**
+     * Returns the workbench.
+     */
+    protected IWorkbench getWorkbench() {
+        return PlatformUI.getWorkbench();
+    }
+
+    /**
+     * Returns the workbench window.
+     */
+    protected IWorkbenchWindow getWorkbenchWindow() {
+        return getNavigator().getSite().getWorkbenchWindow();
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorActionGroup.java
new file mode 100644
index 0000000..7412e98
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorActionGroup.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *        IBM Corporation - initial API and implementation 
+ *        Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * This is the action group for all the resource navigator actions.
+ * It delegates to several subgroups for most of the actions.
+ * 
+ * @see GotoActionGroup
+ * @see OpenActionGroup
+ * @see RefactorActionGroup
+ * @see SortAndFilterActionGroup
+ * @see WorkspaceActionGroup
+ * 
+ * @since 2.0
+ */
+public abstract class ResourceNavigatorActionGroup extends ActionGroup {
+
+    /**
+     * The resource navigator.
+     */
+    protected IResourceNavigator navigator;
+	
+    /**
+     * Constructs a new navigator action group and creates its actions.
+     * 
+     * @param navigator the resource navigator
+     */
+    public ResourceNavigatorActionGroup(IResourceNavigator navigator) {
+        this.navigator = navigator;
+        makeActions();
+    }
+
+    /**
+     * Returns the image descriptor with the given relative path.
+     */
+    protected ImageDescriptor getImageDescriptor(String relativePath) {
+       return IDEWorkbenchPlugin.getIDEImageDescriptor(relativePath);
+     
+    }
+
+    /**
+     * Returns the resource navigator.
+     */
+    public IResourceNavigator getNavigator() {
+        return navigator;
+    }
+
+    /**
+     * Handles a key pressed event by invoking the appropriate action.
+     * Does nothing by default.
+     */
+    public void handleKeyPressed(KeyEvent event) {
+    }
+
+    /**
+     * Makes the actions contained in this action group.
+     */
+    protected abstract void makeActions();
+
+    /**
+     * Runs the default action in the group.
+     * Does nothing by default.
+     * 
+     * @param selection the current selection
+     */
+    public void runDefaultAction(IStructuredSelection selection) {
+    }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMessages.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMessages.java
new file mode 100644
index 0000000..56bb2cc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMessages.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+
+/**
+ * Utility class which helps managing messages
+ * @since 2.0
+ * @deprecated These messages are not API and should not be referenced
+ * outside of this plug-in.
+ */
+public class ResourceNavigatorMessages {
+    
+	private ResourceNavigatorMessages() {
+        // prevent instantiation of class
+    }
+
+    /**
+     * Returns the formatted message for the given key in
+     * the resource bundle. 
+     *
+     * @param key the resource name
+     * @param args the message arguments
+     * @return the string
+     */
+    public static String format(String key, Object[] args) {
+        return key;
+    }
+
+    /**
+     * Returns the resource object with the given key in
+     * the resource bundle. If there isn't any value under
+     * the given key, the key is returned.
+     *
+     * @param key the resource name
+     * @return the string
+     */
+    public static String getString(String key) {
+        return key;
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMoveAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMoveAction.java
new file mode 100644
index 0000000..381b29a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMoveAction.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.MoveProjectAction;
+import org.eclipse.ui.actions.MoveResourceAction;
+
+/**
+ * The ResourceNavigatorMoveAction is a resource move that aso updates the navigator
+ * to show the result of the move.
+ * It also delegates to MoveProjectAction as needed.
+ * 
+ * @since 2.0
+ */
+public class ResourceNavigatorMoveAction extends MoveResourceAction {
+    private StructuredViewer viewer;
+
+    private MoveProjectAction moveProjectAction;
+
+    /**
+     * Create a ResourceNavigatorMoveAction and use the supplied viewer to update the UI.
+     * @param shell Shell
+     * @param structureViewer StructuredViewer
+     */
+    public ResourceNavigatorMoveAction(Shell shell,
+            StructuredViewer structureViewer) {
+        super(shell);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                INavigatorHelpContextIds.RESOURCE_NAVIGATOR_MOVE_ACTION);
+        this.viewer = structureViewer;
+        this.moveProjectAction = new MoveProjectAction(shell);
+    }
+
+    /* (non-Javadoc)
+     * Method declared on IAction.
+     */
+    public void run() {
+        if (moveProjectAction.isEnabled()) {
+            moveProjectAction.run();
+            return;
+        }
+
+        super.run();
+        List destinations = getDestinations();
+        if (destinations != null && destinations.isEmpty() == false) {
+            IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+            List resources = new ArrayList();
+            Iterator iterator = destinations.iterator();
+
+            while (iterator.hasNext()) {
+                IResource newResource = root
+                        .findMember((IPath) iterator.next());
+                if (newResource != null) {
+					resources.add(newResource);
+				}
+            }
+
+            this.viewer.setSelection(new StructuredSelection(resources), true);
+        }
+
+    }
+
+    protected boolean updateSelection(IStructuredSelection selection) {
+        moveProjectAction.selectionChanged(selection);
+        return super.updateSelection(selection)
+                || moveProjectAction.isEnabled();
+    }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorRenameAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorRenameAction.java
new file mode 100644
index 0000000..c9f9ff9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorRenameAction.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.RenameResourceAction;
+
+/**
+ * The ResourceNavigatorRenameAction is the rename action used by the
+ * ResourceNavigator that also allows updating after rename.
+ * @since 2.0
+ */
+public class ResourceNavigatorRenameAction extends RenameResourceAction {
+    private TreeViewer viewer;
+
+    /**
+     * Create a ResourceNavigatorRenameAction and use the tree of the supplied viewer
+     * for editing.
+     * @param shell Shell
+     * @param treeViewer TreeViewer
+     */
+    public ResourceNavigatorRenameAction(Shell shell, TreeViewer treeViewer) {
+        super(shell, treeViewer.getTree());
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+                INavigatorHelpContextIds.RESOURCE_NAVIGATOR_RENAME_ACTION);
+        this.viewer = treeViewer;
+    }
+
+    /* (non-Javadoc)
+     * Run the action to completion using the supplied path.
+     */
+    protected void runWithNewPath(IPath path, IResource resource) {
+        IWorkspaceRoot root = resource.getProject().getWorkspace().getRoot();
+        super.runWithNewPath(path, resource);
+        if (this.viewer != null) {
+            IResource newResource = root.findMember(path);
+            if (newResource != null) {
+				this.viewer.setSelection(new StructuredSelection(newResource),
+                        true);
+			}
+        }
+    }
+
+    /**
+     * Handle the key release
+     */
+    public void handleKeyReleased(KeyEvent event) {
+        if (event.keyCode == SWT.F2 && event.stateMask == 0 && isEnabled()) {
+            run();
+        }
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourcePatternFilter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourcePatternFilter.java
new file mode 100644
index 0000000..5baa8be
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourcePatternFilter.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.util.PrefUtil;
+
+/**
+ * Filter used to determine whether resources are to be shown or not.
+ * 
+ * @since 2.0
+ */
+public class ResourcePatternFilter extends ViewerFilter {
+    private String[] patterns;
+
+    private StringMatcher[] matchers;
+
+    static final String COMMA_SEPARATOR = ",";//$NON-NLS-1$
+
+    static final String FILTERS_TAG = "resourceFilters";//$NON-NLS-1$
+
+    /**
+     * Creates a new resource pattern filter.
+     */
+    public ResourcePatternFilter() {
+        super();
+    }
+
+    /**
+     * Return the currently configured StringMatchers. If there aren't any look
+     * them up.
+     */
+    private StringMatcher[] getMatchers() {
+
+        if (this.matchers == null) {
+			initializeFromPreferences();
+		}
+
+        return this.matchers;
+    }
+
+    /**
+     * Gets the patterns for the receiver. Returns the cached values if there
+     * are any - if not look it up.
+     */
+    public String[] getPatterns() {
+
+        if (this.patterns == null) {
+			initializeFromPreferences();
+		}
+
+        return this.patterns;
+
+    }
+
+    /**
+     * Initializes the filters from the preference store.
+     */
+    private void initializeFromPreferences() {
+        // get the filters that were saved by ResourceNavigator.setFiltersPreference
+        IPreferenceStore viewsPrefs = IDEWorkbenchPlugin.getDefault()
+                .getPreferenceStore();
+        String storedPatterns = viewsPrefs.getString(FILTERS_TAG);
+
+        if (storedPatterns.length() == 0) {
+            // try to migrate patterns from old workbench preference store location
+            IPreferenceStore workbenchPrefs = PrefUtil.getInternalPreferenceStore();
+            storedPatterns = workbenchPrefs.getString(FILTERS_TAG);
+            if (storedPatterns.length() > 0) {
+                viewsPrefs.setValue(FILTERS_TAG, storedPatterns);
+                workbenchPrefs.setValue(FILTERS_TAG, ""); //$NON-NLS-1$
+            }
+        }
+
+        if (storedPatterns.length() == 0) {
+            // revert to all filter extensions with selected == "true"
+            // if there are no filters in the preference store
+            List defaultFilters = FiltersContentProvider.getDefaultFilters();
+            String[] patterns = new String[defaultFilters.size()];
+            defaultFilters.toArray(patterns);
+            setPatterns(patterns);
+            return;
+        }
+
+        //Get the strings separated by a comma and filter them from the currently
+        //defined ones
+        List definedFilters = FiltersContentProvider.getDefinedFilters();
+        StringTokenizer entries = new StringTokenizer(storedPatterns,
+                COMMA_SEPARATOR);
+        List patterns = new ArrayList();
+
+        while (entries.hasMoreElements()) {
+            String nextToken = entries.nextToken();
+            if (definedFilters.indexOf(nextToken) > -1) {
+				patterns.add(nextToken);
+			}
+        }
+
+        //Convert to an array of Strings
+        String[] patternArray = new String[patterns.size()];
+        patterns.toArray(patternArray);
+        setPatterns(patternArray);
+
+    }
+
+    /* (non-Javadoc)
+     * Method declared on ViewerFilter.
+     */
+    public boolean select(Viewer viewer, Object parentElement, Object element) {
+        IResource resource = null;
+        if (element instanceof IResource) {
+            resource = (IResource) element;
+        } else if (element instanceof IAdaptable) {
+            IAdaptable adaptable = (IAdaptable) element;
+            resource = (IResource) adaptable.getAdapter(IResource.class);
+        }
+        if (resource != null) {
+            String name = resource.getName();
+            StringMatcher[] testMatchers = getMatchers();
+            for (int i = 0; i < testMatchers.length; i++) {
+                if (testMatchers[i].match(name)) {
+					return false;
+				}
+            }
+            return true;
+        }
+        return true;
+    }
+
+    /**
+     * Sets the patterns to filter out for the receiver.
+     */
+    public void setPatterns(String[] newPatterns) {
+
+        this.patterns = newPatterns;
+        this.matchers = new StringMatcher[newPatterns.length];
+        for (int i = 0; i < newPatterns.length; i++) {
+            //Reset the matchers to prevent constructor overhead
+            matchers[i] = new StringMatcher(newPatterns[i], true, false);
+        }
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSelectionUtil.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSelectionUtil.java
new file mode 100644
index 0000000..9fa7a0d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSelectionUtil.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+
+/**
+ * Provides utilities for checking the validity of selections.
+ * <p>
+ * This class provides static methods only; it is not intended to be instantiated
+ * or subclassed.
+ * @since 2.0
+ * </p>
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ResourceSelectionUtil {
+    /* (non-Javadoc)
+     * Private constructor to block instantiation.
+     */
+    private ResourceSelectionUtil() {
+    }
+
+    /**
+     * Returns whether the types of the resources in the given selection are among 
+     * the specified resource types.
+     * 
+     * @param selection the selection
+     * @param resourceMask resource mask formed by bitwise OR of resource type
+     *   constants (defined on <code>IResource</code>)
+     * @return <code>true</code> if all selected elements are resources of the right
+     *  type, and <code>false</code> if at least one element is either a resource
+     *  of some other type or a non-resource
+     * @see IResource#getType()
+     */
+    public static boolean allResourcesAreOfType(IStructuredSelection selection,
+            int resourceMask) {
+        Iterator resources = selection.iterator();
+        while (resources.hasNext()) {
+            Object next = resources.next();
+            if (!(next instanceof IResource)) {
+				return false;
+			}
+            if (!resourceIsType((IResource) next, resourceMask)) {
+				return false;
+			}
+        }
+        return true;
+    }
+
+    /**
+     * Returns the selection adapted to IResource. Returns null
+     * if any of the entries are not adaptable.
+     * 
+     * @param selection the selection
+     * @param resourceMask resource mask formed by bitwise OR of resource type
+     *   constants (defined on <code>IResource</code>)
+     * @return IStructuredSelection or null if any of the entries are not adaptable.
+     * @see IResource#getType()
+     */
+    public static IStructuredSelection allResources(
+            IStructuredSelection selection, int resourceMask) {
+        Iterator adaptables = selection.iterator();
+        List result = new ArrayList();
+        while (adaptables.hasNext()) {
+            Object next = adaptables.next();
+            if (next instanceof IAdaptable) {
+                Object resource = ((IAdaptable) next)
+                        .getAdapter(IResource.class);
+                if (resource == null) {
+					return null;
+				} else if (resourceIsType((IResource) resource, resourceMask)) {
+					result.add(resource);
+				}
+            } else {
+				return null;
+			}
+        }
+        return new StructuredSelection(result);
+
+    }
+
+    /**
+     * Returns whether the type of the given resource is among the specified 
+     * resource types.
+     * 
+     * @param resource the resource
+     * @param resourceMask resource mask formed by bitwise OR of resource type
+     *   constants (defined on <code>IResource</code>)
+     * @return <code>true</code> if the resources has a matching type, and 
+     *   <code>false</code> otherwise
+     * @see IResource#getType()
+     */
+    public static boolean resourceIsType(IResource resource, int resourceMask) {
+        return (resource.getType() & resourceMask) != 0;
+    }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSorter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSorter.java
new file mode 100644
index 0000000..aad368c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSorter.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+/**
+ * Sorter for viewers that display items of type <code>IResource</code>.
+ * The sorter supports two sort criteria:
+ * <p>
+ * <code>NAME</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by name.  All name comparisons
+ * are case-insensitive.
+ * </p>
+ * <p>
+ * <code>TYPE</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by extension.  All extension
+ * comparisons are case-insensitive.
+ * </p>
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @deprecated as of 3.3, use {@link ResourceComparator} instead
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ResourceSorter extends ViewerSorter {
+
+    /**
+     * Constructor argument value that indicates to sort items by name.
+     */
+    public final static int NAME = 1;
+
+    /**
+     * Constructor argument value that indicates to sort items by extension.
+     */
+    public final static int TYPE = 2;
+
+    private int criteria;
+
+    /**
+     * Creates a resource sorter that will use the given sort criteria.
+     *
+     * @param criteria the sort criterion to use: one of <code>NAME</code> or 
+     *   <code>TYPE</code>
+     */
+    public ResourceSorter(int criteria) {
+        super();
+        this.criteria = criteria;
+    }
+
+    /**
+     * Returns an integer value representing the relative sort priority of the 
+     * given element based on its class.
+     * <p>
+     * <ul>
+     *   <li>resources (<code>IResource</code>) - 2</li>
+     *   <li>project references (<code>ProjectReference</code>) - 1</li>
+     *   <li>everything else - 0</li>
+     * </ul>
+     * </p>
+     *
+     * @param element the element
+     * @return the sort priority (larger numbers means more important)
+     */
+    protected int classComparison(Object element) {
+        if (element instanceof IResource) {
+            return 2;
+        }
+        return 0;
+    }
+
+    /* (non-Javadoc)
+     * Method declared on ViewerSorter.
+     */
+    public int compare(Viewer viewer, Object o1, Object o2) {
+        //have to deal with non-resources in navigator
+        //if one or both objects are not resources, returned a comparison 
+        //based on class.
+        if (!(o1 instanceof IResource && o2 instanceof IResource)) {
+            return compareClass(o1, o2);
+        }
+        IResource r1 = (IResource) o1;
+        IResource r2 = (IResource) o2;
+
+        if (r1 instanceof IContainer && r2 instanceof IContainer) {
+			return compareNames(r1, r2);
+		} else if (r1 instanceof IContainer) {
+			return -1;
+		} else if (r2 instanceof IContainer) {
+			return 1;
+		} else if (criteria == NAME) {
+			return compareNames(r1, r2);
+		} else if (criteria == TYPE) {
+			return compareTypes(r1, r2);
+		} else {
+			return 0;
+		}
+    }
+
+    /**
+     * Returns a number reflecting the collation order of the given elements
+     * based on their class.
+     *
+     * @param element1 the first element to be ordered
+     * @param element2 the second element to be ordered
+     * @return a negative number if the first element is less  than the 
+     *  second element; the value <code>0</code> if the first element is
+     *  equal to the second element; and a positive number if the first
+     *  element is greater than the second element
+     */
+    protected int compareClass(Object element1, Object element2) {
+        return classComparison(element1) - classComparison(element2);
+    }
+
+    /**
+     * Returns a number reflecting the collation order of the given resources
+     * based on their resource names.
+     *
+     * @param resource1 the first resource element to be ordered
+     * @param resource2 the second resource element to be ordered
+     * @return a negative number if the first element is less  than the 
+     *  second element; the value <code>0</code> if the first element is
+     *  equal to the second element; and a positive number if the first
+     *  element is greater than the second element
+     */
+    protected int compareNames(IResource resource1, IResource resource2) {
+        return collator.compare(resource1.getName(), resource2.getName());
+    }
+
+    /**
+     * Returns a number reflecting the collation order of the given resources
+     * based on their respective file extensions. Resources with the same file
+     * extension will be collated based on their names.
+     *
+     * @param resource1 the first resource element to be ordered
+     * @param resource2 the second resource element to be ordered
+     * @return a negative number if the first element is less  than the 
+     *  second element; the value <code>0</code> if the first element is
+     *  equal to the second element; and a positive number if the first
+     *  element is greater than the second element
+     */
+    protected int compareTypes(IResource resource1, IResource resource2) {
+        String ext1 = getExtensionFor(resource1);
+        String ext2 = getExtensionFor(resource2);
+
+        // Compare extensions.  If they're different then return a value that
+        // indicates correct extension ordering.  If they're the same then
+        // return a value that indicates the correct NAME ordering.
+        int result = collator.compare(ext1, ext2);
+
+        if (result != 0) {
+			return result;
+		}
+
+        return compareNames(resource1, resource2);
+    }
+
+    /**
+     * Returns the sort criteria of this sorter.
+     *
+     * @return the sort criterion: one of <code>NAME</code> or <code>TYPE</code>
+     */
+    public int getCriteria() {
+        return criteria;
+    }
+
+    /**
+     * Returns the extension portion of the given resource.
+     *
+     * @param resource the resource
+     * @return the file extension, possibily the empty string
+     */
+    private String getExtensionFor(IResource resource) {
+        String ext = resource.getFileExtension();
+        return ext == null ? "" : ext; //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the sort criteria of this sorter.
+     * 
+     * @param criteria the sort criterion: 
+     *	one of <code>ResourceSorter.NAME</code> or 
+     *	<code>ResourceSorter.TYPE</code>
+     */
+    public void setCriteria(int criteria) {
+        this.criteria = criteria;
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ShowInNavigatorAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ShowInNavigatorAction.java
new file mode 100644
index 0000000..0ed009a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ShowInNavigatorAction.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.actions.SelectionProviderAction;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ISetSelectionTarget;
+
+/**
+ * An action which shows the current selection in the Navigator view.
+ * For each element in the selection, if it is an <code>IResource</code>
+ * it uses it directly, otherwise if it is an <code>IMarker</code> it uses the marker's resource,
+ * otherwise if it is an <code>IAdaptable</code>, it tries to get the <code>IResource.class</code> adapter.
+ */
+public class ShowInNavigatorAction extends SelectionProviderAction {
+    private IWorkbenchPage page;
+
+    /**
+     * Create a new instance of this class.
+     * 
+     * @param page the page
+     * @param viewer the viewer
+     */
+    public ShowInNavigatorAction(IWorkbenchPage page, ISelectionProvider viewer) {
+        super(viewer, ResourceNavigatorMessages.ShowInNavigator_text);
+        Assert.isNotNull(page);
+        this.page = page;
+        setDescription(ResourceNavigatorMessages.ShowInNavigator_toolTip);
+        page.getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(this,
+				INavigatorHelpContextIds.SHOW_IN_NAVIGATOR_ACTION);
+    }
+
+    /**
+     * Returns the resources in the given selection.
+     *
+     * @return a list of <code>IResource</code>
+     */
+    List getResources(IStructuredSelection selection) {
+        List v = new ArrayList();
+        for (Iterator i = selection.iterator(); i.hasNext();) {
+            Object o = i.next();
+            if (o instanceof IResource) {
+                v.add(o);
+            } else if (o instanceof IMarker) {
+                IResource resource = ((IMarker) o).getResource();
+                v.add(resource);
+            } else if (o instanceof IAdaptable) {
+                IResource resource = (IResource) ((IAdaptable) o)
+                        .getAdapter(IResource.class);
+                if (resource != null) {
+                    v.add(resource);
+                }
+            }
+        }
+        return v;
+    }
+
+    /*
+     * (non-Javadoc)
+     * Method declared on IAction.
+     */
+    /**
+     * Shows the Navigator view and sets its selection to the resources
+     * selected in this action's selection provider.
+     */
+    public void run() {
+        List v = getResources(getStructuredSelection());
+        if (v.isEmpty()) {
+			return;
+		}
+        try {
+            IViewPart view = page.showView(IPageLayout.ID_RES_NAV);
+            if (view instanceof ISetSelectionTarget) {
+                ISelection selection = new StructuredSelection(v);
+                ((ISetSelectionTarget) view).selectReveal(selection);
+            }
+        } catch (PartInitException e) {
+            ErrorDialog.openError(page.getWorkbenchWindow().getShell(),
+                    ResourceNavigatorMessages.ShowInNavigator_errorMessage,
+                    e.getMessage(), e.getStatus());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * Method declared on SelectionProviderAction.
+     */
+    public void selectionChanged(IStructuredSelection selection) {
+        setEnabled(!getResources(selection).isEmpty());
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortAndFilterActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortAndFilterActionGroup.java
new file mode 100644
index 0000000..38e4cec
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortAndFilterActionGroup.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * This is the action group for the sort and filter actions.
+ */
+public class SortAndFilterActionGroup extends ResourceNavigatorActionGroup {
+
+    private SortViewAction sortByTypeAction;
+
+    private SortViewAction sortByNameAction;
+
+    private FilterSelectionAction filterAction;
+
+    /**
+     * Constructor. 
+     * 
+     * @param navigator
+     */
+    public SortAndFilterActionGroup(IResourceNavigator navigator) {
+        super(navigator);
+    }
+
+    protected void makeActions() {
+        sortByNameAction = new SortViewAction(navigator, false);
+        sortByTypeAction = new SortViewAction(navigator, true);
+
+        filterAction = new FilterSelectionAction(navigator,
+                ResourceNavigatorMessages.ResourceNavigator_filterText);
+        filterAction
+                .setDisabledImageDescriptor(getImageDescriptor("dlcl16/filter_ps.gif"));//$NON-NLS-1$
+        filterAction
+                .setImageDescriptor(getImageDescriptor("elcl16/filter_ps.gif"));//$NON-NLS-1$
+    }
+
+    public void fillActionBars(IActionBars actionBars) {
+        IMenuManager menu = actionBars.getMenuManager();
+        IMenuManager submenu = new MenuManager(ResourceNavigatorMessages.ResourceNavigator_sort);
+        menu.add(submenu);
+        submenu.add(sortByNameAction);
+        submenu.add(sortByTypeAction);
+        menu.add(filterAction);
+    }
+
+    public void updateActionBars() {
+        int criteria = navigator.getComparator().getCriteria();
+        sortByNameAction.setChecked(criteria == ResourceComparator.NAME);
+        sortByTypeAction.setChecked(criteria == ResourceComparator.TYPE);
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortViewAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortViewAction.java
new file mode 100644
index 0000000..c2da71a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortViewAction.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * Implementation of the view sorting actions.
+ * @since 2.0
+ */
+public class SortViewAction extends ResourceNavigatorAction {
+    private int sortCriteria;
+
+    /**
+     * Creates the action.
+     *
+     * @param navigator the resource navigator
+     * @param sortByType <code>true</code> for sort by type, <code>false</code> for sort by name
+     */
+    public SortViewAction(IResourceNavigator navigator, boolean sortByType) {
+        super(
+                navigator,
+                sortByType ? ResourceNavigatorMessages.SortView_byType : ResourceNavigatorMessages.SortView_byName);
+        if (sortByType) {
+            setToolTipText(ResourceNavigatorMessages.SortView_toolTipByType);
+        } else {
+            setToolTipText(ResourceNavigatorMessages.SortView_toolTipByName);
+        }
+        setEnabled(true);
+        sortCriteria = sortByType ? ResourceComparator.TYPE : ResourceComparator.NAME;
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+				INavigatorHelpContextIds.SORT_VIEW_ACTION);
+    }
+
+    public void run() {
+        IResourceNavigator navigator = getNavigator();
+        ResourceComparator comparator = navigator.getComparator();
+
+        if (comparator == null) {
+			navigator.setComparator(new ResourceComparator(sortCriteria));
+		} else {
+			comparator.setCriteria(sortCriteria);
+            navigator.setComparator(comparator);
+        }
+
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/StringMatcher.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/StringMatcher.java
new file mode 100644
index 0000000..f9acac2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/StringMatcher.java
@@ -0,0 +1,449 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.Vector;
+
+/**
+ * A string pattern matcher, suppporting ?*? and ??? wildcards.
+ */
+/* package */class StringMatcher {
+    protected String fPattern;
+
+    protected int fLength; // pattern length
+
+    protected boolean fIgnoreWildCards;
+
+    protected boolean fIgnoreCase;
+
+    protected boolean fHasLeadingStar;
+
+    protected boolean fHasTrailingStar;
+
+    protected String fSegments[]; //the given pattern is split into * separated segments
+
+    /* boundary value beyond which we don't need to search in the text */
+    protected int fBound = 0;
+
+    protected static final char fSingleWildCard = '\u0000';
+
+    public static class Position {
+        int start; //inclusive
+
+        int end; //exclusive
+
+        public Position(int start, int end) {
+            this.start = start;
+            this.end = end;
+        }
+
+        public int getStart() {
+            return start;
+        }
+
+        public int getEnd() {
+            return end;
+        }
+    }
+
+    /**
+     * StringMatcher constructor takes in a String object that is a simple 
+     * pattern which may contain '*' for 0 and many characters and
+     * '?' for exactly one character.  
+     *
+     * Literal '*' and '?' characters must be escaped in the pattern 
+     * e.g., "\*" means literal "*", etc.
+     *
+     * Escaping any other character (including the escape character itself), 
+     * just results in that character in the pattern.
+     * e.g., "\a" means "a" and "\\" means "\"
+     *
+     * If invoking the StringMatcher with string literals in Java, don't forget
+     * escape characters are represented by "\\".
+     *
+     * @param pattern the pattern to match text against
+     * @param ignoreCase if true, case is ignored
+     * @param ignoreWildCards if true, wild cards and their escape sequences are ignored
+     * 		  (everything is taken literally).
+     */
+    public StringMatcher(String pattern, boolean ignoreCase,
+            boolean ignoreWildCards) {
+        if (pattern == null) {
+			throw new IllegalArgumentException();
+		}
+        fIgnoreCase = ignoreCase;
+        fIgnoreWildCards = ignoreWildCards;
+        fPattern = pattern;
+        fLength = pattern.length();
+
+        if (fIgnoreWildCards) {
+            parseNoWildCards();
+        } else {
+            parseWildCards();
+        }
+    }
+
+    /**
+     * Find the first occurrence of the pattern between <code>start</code)(inclusive) 
+     * and <code>end</code>(exclusive).  
+     * @param <code>text</code>, the String object to search in 
+     * @param <code>start</code>, the starting index of the search range, inclusive
+     * @param <code>end</code>, the ending index of the search range, exclusive
+     * @return an <code>StringMatcher.Position</code> object that keeps the starting 
+     * (inclusive) and ending positions (exclusive) of the first occurrence of the 
+     * pattern in the specified range of the text; return null if not found or subtext
+     * is empty (start==end). A pair of zeros is returned if pattern is empty string
+     * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
+     * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
+     */
+    public StringMatcher.Position find(String text, int start, int end) {
+        if (text == null) {
+			throw new IllegalArgumentException();
+		}
+
+        int tlen = text.length();
+        if (start < 0) {
+			start = 0;
+		}
+        if (end > tlen) {
+			end = tlen;
+		}
+        if (end < 0 || start >= end) {
+			return null;
+		}
+        if (fLength == 0) {
+			return new Position(start, start);
+		}
+        if (fIgnoreWildCards) {
+            int x = posIn(text, start, end);
+            if (x < 0) {
+				return null;
+			}
+            return new Position(x, x + fLength);
+        }
+
+        int segCount = fSegments.length;
+        if (segCount == 0) {
+			return new Position(start, end);
+		}
+
+        int curPos = start;
+        int matchStart = -1;
+        int i;
+        for (i = 0; i < segCount && curPos < end; ++i) {
+            String current = fSegments[i];
+            int nextMatch = regExpPosIn(text, curPos, end, current);
+            if (nextMatch < 0) {
+				return null;
+			}
+            if (i == 0) {
+				matchStart = nextMatch;
+			}
+            curPos = nextMatch + current.length();
+        }
+        if (i < segCount) {
+			return null;
+		}
+        return new Position(matchStart, curPos);
+    }
+
+    /**
+     * match the given <code>text</code> with the pattern 
+     * @return true if matched eitherwise false
+     * @param <code>text</code>, a String object 
+     */
+    public boolean match(String text) {
+        return match(text, 0, text.length());
+    }
+
+    /**
+     * Given the starting (inclusive) and the ending (exclusive) poisitions in the   
+     * <code>text</code>, determine if the given substring matches with aPattern  
+     * @return true if the specified portion of the text matches the pattern
+     * @param String <code>text</code>, a String object that contains the substring to match 
+     * @param int <code>start<code> marks the starting position (inclusive) of the substring
+     * @param int <code>end<code> marks the ending index (exclusive) of the substring 
+     */
+    public boolean match(String text, int start, int end) {
+        if (null == text) {
+			throw new IllegalArgumentException();
+		}
+
+        if (start > end) {
+			return false;
+		}
+
+        if (fIgnoreWildCards) {
+			return (end - start == fLength)
+                    && fPattern.regionMatches(fIgnoreCase, 0, text, start,
+                            fLength);
+		}
+        int segCount = fSegments.length;
+        if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) {
+			return true;
+		}
+        if (start == end) {
+			return fLength == 0;
+		}
+        if (fLength == 0) {
+			return start == end;
+		}
+
+        int tlen = text.length();
+        if (start < 0) {
+			start = 0;
+		}
+        if (end > tlen) {
+			end = tlen;
+		}
+
+        int tCurPos = start;
+        int bound = end - fBound;
+        if (bound < 0) {
+			return false;
+		}
+        int i = 0;
+        String current = fSegments[i];
+        int segLength = current.length();
+
+        /* process first segment */
+        if (!fHasLeadingStar) {
+            if (!regExpRegionMatches(text, start, current, 0, segLength)) {
+                return false;
+            } else {
+                ++i;
+                tCurPos = tCurPos + segLength;
+            }
+        }
+        if ((fSegments.length == 1) && (!fHasLeadingStar)
+                && (!fHasTrailingStar)) {
+            // only one segment to match, no wildcards specified
+            return tCurPos == end;
+        }
+        /* process middle segments */
+        for (; i < segCount && tCurPos <= bound; ++i) {
+            current = fSegments[i];
+            int currentMatch;
+            int k = current.indexOf(fSingleWildCard);
+            if (k < 0) {
+                currentMatch = textPosIn(text, tCurPos, end, current);
+                if (currentMatch < 0) {
+					return false;
+				}
+            } else {
+                currentMatch = regExpPosIn(text, tCurPos, end, current);
+                if (currentMatch < 0) {
+					return false;
+				}
+            }
+            tCurPos = currentMatch + current.length();
+        }
+
+        /* process final segment */
+        if (!fHasTrailingStar && tCurPos != end) {
+            int clen = current.length();
+            return regExpRegionMatches(text, end - clen, current, 0, clen);
+        }
+        return i == segCount;
+    }
+
+    /**
+     * This method parses the given pattern into segments seperated by wildcard '*' characters.
+     * Since wildcards are not being used in this case, the pattern consists of a single segment.
+     */
+    private void parseNoWildCards() {
+        fSegments = new String[1];
+        fSegments[0] = fPattern;
+        fBound = fLength;
+    }
+
+    /**
+     * Parses the given pattern into segments seperated by wildcard '*' characters.
+     * @param p, a String object that is a simple regular expression with '*' and/or '?'
+     */
+    private void parseWildCards() {
+        if (fPattern.startsWith("*")) { //$NON-NLS-1$
+			fHasLeadingStar = true;
+		}
+        if (fPattern.endsWith("*")) {//$NON-NLS-1$
+            /* make sure it's not an escaped wildcard */
+            if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
+                fHasTrailingStar = true;
+            }
+        }
+
+        Vector temp = new Vector();
+
+        int pos = 0;
+        StringBuffer buf = new StringBuffer();
+        while (pos < fLength) {
+            char c = fPattern.charAt(pos++);
+            switch (c) {
+            case '\\':
+                if (pos >= fLength) {
+                    buf.append(c);
+                } else {
+                    char next = fPattern.charAt(pos++);
+                    /* if it's an escape sequence */
+                    if (next == '*' || next == '?' || next == '\\') {
+                        buf.append(next);
+                    } else {
+                        /* not an escape sequence, just insert literally */
+                        buf.append(c);
+                        buf.append(next);
+                    }
+                }
+                break;
+            case '*':
+                if (buf.length() > 0) {
+                    /* new segment */
+                    temp.addElement(buf.toString());
+                    fBound += buf.length();
+                    buf.setLength(0);
+                }
+                break;
+            case '?':
+                /* append special character representing single match wildcard */
+                buf.append(fSingleWildCard);
+                break;
+            default:
+                buf.append(c);
+            }
+        }
+
+        /* add last buffer to segment list */
+        if (buf.length() > 0) {
+            temp.addElement(buf.toString());
+            fBound += buf.length();
+        }
+
+        fSegments = new String[temp.size()];
+        temp.copyInto(fSegments);
+    }
+
+    /** 
+     * @param <code>text</code>, a string which contains no wildcard
+     * @param <code>start</code>, the starting index in the text for search, inclusive
+     * @param <code>end</code>, the stopping point of search, exclusive
+     * @return the starting index in the text of the pattern , or -1 if not found 
+     */
+    protected int posIn(String text, int start, int end) {//no wild card in pattern
+        int max = end - fLength;
+
+        if (!fIgnoreCase) {
+            int i = text.indexOf(fPattern, start);
+            if (i == -1 || i > max) {
+				return -1;
+			}
+            return i;
+        }
+
+        for (int i = start; i <= max; ++i) {
+            if (text.regionMatches(true, i, fPattern, 0, fLength)) {
+				return i;
+			}
+        }
+
+        return -1;
+    }
+
+    /** 
+     * @param <code>text</code>, a simple regular expression that may only contain '?'(s)
+     * @param <code>start</code>, the starting index in the text for search, inclusive
+     * @param <code>end</code>, the stopping point of search, exclusive
+     * @param <code>p</code>, a simple regular expression that may contains '?'
+     * @param <code>caseIgnored</code>, wether the pattern is not casesensitive
+     * @return the starting index in the text of the pattern , or -1 if not found 
+     */
+    protected int regExpPosIn(String text, int start, int end, String p) {
+        int plen = p.length();
+
+        int max = end - plen;
+        for (int i = start; i <= max; ++i) {
+            if (regExpRegionMatches(text, i, p, 0, plen)) {
+				return i;
+			}
+        }
+        return -1;
+    }
+
+    /**
+     * 
+     * @return boolean
+     * @param <code>text</code>, a String to match
+     * @param <code>start</code>, int that indicates the starting index of match, inclusive
+     * @param <code>end</code> int that indicates the ending index of match, exclusive
+     * @param <code>p</code>, String,  String, a simple regular expression that may contain '?'
+     * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive
+     */
+    protected boolean regExpRegionMatches(String text, int tStart, String p,
+            int pStart, int plen) {
+        while (plen-- > 0) {
+            char tchar = text.charAt(tStart++);
+            char pchar = p.charAt(pStart++);
+
+            /* process wild cards */
+            if (!fIgnoreWildCards) {
+                /* skip single wild cards */
+                if (pchar == fSingleWildCard) {
+                    continue;
+                }
+            }
+            if (pchar == tchar) {
+				continue;
+			}
+            if (fIgnoreCase) {
+                if (Character.toUpperCase(tchar) == Character
+                        .toUpperCase(pchar)) {
+					continue;
+				}
+                // comparing after converting to upper case doesn't handle all cases;
+                // also compare after converting to lower case
+                if (Character.toLowerCase(tchar) == Character
+                        .toLowerCase(pchar)) {
+					continue;
+				}
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /** 
+     * @param <code>text</code>, the string to match
+     * @param <code>start</code>, the starting index in the text for search, inclusive
+     * @param <code>end</code>, the stopping point of search, exclusive
+     * @param code>p</code>, a string that has no wildcard
+     * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive
+     * @return the starting index in the text of the pattern , or -1 if not found 
+     */
+    protected int textPosIn(String text, int start, int end, String p) {
+
+        int plen = p.length();
+        int max = end - plen;
+
+        if (!fIgnoreCase) {
+            int i = text.indexOf(p, start);
+            if (i == -1 || i > max) {
+				return -1;
+			}
+            return i;
+        }
+
+        for (int i = 0; i <= max; ++i) {
+            if (text.regionMatches(true, i, p, 0, plen)) {
+				return i;
+			}
+        }
+
+        return -1;
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ToggleLinkingAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ToggleLinkingAction.java
new file mode 100644
index 0000000..54b0539
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ToggleLinkingAction.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.e4.demio.views.nav;
+
+/**
+ * This action toggles whether this navigator links its selection to the active
+ * editor.
+ * 
+ * @since 2.1
+ */
+public class ToggleLinkingAction extends ResourceNavigatorAction {
+
+	private static final String COMMAND_ID = "org.eclipse.ui.navigate.linkWithEditor"; //$NON-NLS-1$
+
+	/**
+     * Constructs a new action.
+     */
+    public ToggleLinkingAction(IResourceNavigator navigator, String label) {
+        super(navigator, label);
+        setActionDefinitionId(COMMAND_ID);
+        setChecked(navigator.isLinkingEnabled());
+    }
+
+    /**
+     * Runs the action.
+     */
+    public void run() {
+        getNavigator().setLinkingEnabled(isChecked());
+    }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/WorkspaceActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/WorkspaceActionGroup.java
new file mode 100644
index 0000000..2b20d4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/WorkspaceActionGroup.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.BuildAction;
+import org.eclipse.ui.actions.CloseResourceAction;
+import org.eclipse.ui.actions.CloseUnrelatedProjectsAction;
+import org.eclipse.ui.actions.OpenResourceAction;
+import org.eclipse.ui.actions.RefreshAction;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.StatusUtil;
+
+/**
+ * This is the action group for workspace actions such as Build, Refresh Local,
+ * and Open/Close Project.
+ */
+public class WorkspaceActionGroup extends ResourceNavigatorActionGroup {
+
+    private BuildAction buildAction;
+
+    private OpenResourceAction openProjectAction;
+
+    private CloseResourceAction closeProjectAction;
+    
+    private CloseUnrelatedProjectsAction closeUnrelatedProjectsAction;
+
+    private RefreshAction refreshAction;
+
+    public WorkspaceActionGroup(IResourceNavigator navigator) {
+        super(navigator);
+    }
+
+    public void fillActionBars(IActionBars actionBars) {
+        actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(),
+                refreshAction);
+        actionBars.setGlobalActionHandler(IDEActionFactory.BUILD_PROJECT
+                .getId(), buildAction);
+        actionBars.setGlobalActionHandler(
+                IDEActionFactory.OPEN_PROJECT.getId(), openProjectAction);
+        actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_PROJECT
+                .getId(), closeProjectAction);
+        actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_UNRELATED_PROJECTS
+                .getId(), closeUnrelatedProjectsAction);
+    }
+
+    /**
+     * Adds the build, open project, close project and refresh resource
+     * actions to the context menu.
+     * <p>
+     * The following conditions apply: 
+     * 	build-only projects selected, auto build disabled, at least one 
+     * 		builder present
+     * 	open project-only projects selected, at least one closed project
+     * 	close project-only projects selected, at least one open project
+     * 	refresh-no closed project selected
+     * </p>
+     * <p>
+     * Both the open project and close project action may be on the menu
+     * at the same time.
+     * </p>
+     * <p>
+     * No disabled action should be on the context menu.
+     * </p>
+     * 
+     * @param menu context menu to add actions to
+     */
+    public void fillContextMenu(IMenuManager menu) {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+        boolean isProjectSelection = true;
+        boolean hasOpenProjects = false;
+        boolean hasClosedProjects = false;
+        boolean hasBuilder = true; // false if any project is closed or does not have builder 
+        Iterator resources = selection.iterator();
+
+        while (resources.hasNext()
+                && (!hasOpenProjects || !hasClosedProjects || hasBuilder || isProjectSelection)) {
+            Object next = resources.next();
+            IProject project = null;
+
+            if (next instanceof IProject) {
+				project = (IProject) next;
+			} else if (next instanceof IAdaptable) {
+				project = (IProject) ((IAdaptable) next)
+                        .getAdapter(IProject.class);
+			}
+
+            if (project == null) {
+                isProjectSelection = false;
+                continue;
+            }
+            if (project.isOpen()) {
+                hasOpenProjects = true;
+                if (hasBuilder && !hasBuilder(project)) {
+					hasBuilder = false;
+				}
+            } else {
+                hasClosedProjects = true;
+                hasBuilder = false;
+            }
+        }
+        if (!selection.isEmpty() && isProjectSelection
+                && !ResourcesPlugin.getWorkspace().isAutoBuilding()
+                && hasBuilder) {
+            // Allow manual incremental build only if auto build is off.
+            buildAction.selectionChanged(selection);
+            menu.add(buildAction);
+        }
+        if (!hasClosedProjects) {
+            refreshAction.selectionChanged(selection);
+            menu.add(refreshAction);
+        }
+        if (isProjectSelection) {
+            if (hasClosedProjects) {
+                openProjectAction.selectionChanged(selection);
+                menu.add(openProjectAction);
+            }
+            if (hasOpenProjects) {
+                closeProjectAction.selectionChanged(selection);
+                menu.add(closeProjectAction);
+                closeUnrelatedProjectsAction.selectionChanged(selection);
+                menu.add(closeUnrelatedProjectsAction);
+            }
+        }
+    }
+
+    /**
+     * Handles a key pressed event by invoking the appropriate action.
+     */
+    public void handleKeyPressed(KeyEvent event) {
+        if (event.keyCode == SWT.F5 && event.stateMask == 0) {
+            if (refreshAction.isEnabled()) {
+                refreshAction.refreshAll();
+            }
+
+            // Swallow the event
+            event.doit = false;
+        }
+    }
+
+    /**
+     * Returns whether there are builders configured on the given project.
+     *
+     * @return <code>true</code> if it has builders,
+     *   <code>false</code> if not, or if this could not be determined
+     */
+    boolean hasBuilder(IProject project) {
+        try {
+            ICommand[] commands = project.getDescription().getBuildSpec();
+            if (commands.length > 0) {
+				return true;
+			}
+        } catch (CoreException e) {
+            // Cannot determine if project has builders. Project is closed 
+            // or does not exist. Fall through to return false.
+        }
+        return false;
+    }
+
+    protected void makeActions() {
+        final IShellProvider provider = navigator.getSite();
+        openProjectAction = new OpenResourceAction(provider);
+        closeProjectAction = new CloseResourceAction(provider);
+        closeUnrelatedProjectsAction = new CloseUnrelatedProjectsAction(provider);
+        refreshAction = new RefreshAction(provider) {
+        	public void run() {
+        		final IStatus[] errorStatus = new IStatus[1];
+        		errorStatus[0] = Status.OK_STATUS;
+        		final WorkspaceModifyOperation op = (WorkspaceModifyOperation) createOperation(errorStatus);
+        		WorkspaceJob job = new WorkspaceJob("refresh") { //$NON-NLS-1$
+
+        			public IStatus runInWorkspace(IProgressMonitor monitor)
+        					throws CoreException {
+        				try {
+        					op.run(monitor);
+        					Shell shell = provider.getShell();
+							if (shell != null && !shell.isDisposed()) {
+								shell.getDisplay().asyncExec(new Runnable() {
+									public void run() {
+										TreeViewer viewer = navigator
+												.getViewer();
+										if (viewer != null
+												&& viewer.getControl() != null
+												&& !viewer.getControl()
+														.isDisposed()) {
+											viewer.refresh();
+										}
+									}
+								});
+							}
+        				} catch (InvocationTargetException e) {
+        					String msg = NLS.bind(
+        							IDEWorkbenchMessages.WorkspaceAction_logTitle, getClass()
+        									.getName(), e.getTargetException());
+        					throw new CoreException(StatusUtil.newStatus(IStatus.ERROR,
+        							msg, e.getTargetException()));
+        				} catch (InterruptedException e) {
+        					return Status.CANCEL_STATUS;
+        				}
+        				return errorStatus[0];
+        			}
+        			
+        		};
+        		ISchedulingRule rule = op.getRule();
+        		if (rule != null) {
+        			job.setRule(rule);
+        		}
+        		job.setUser(true);
+        		job.schedule();
+        	}
+        };
+        refreshAction
+                .setDisabledImageDescriptor(getImageDescriptor("dlcl16/refresh_nav.gif"));//$NON-NLS-1$
+        refreshAction
+                .setImageDescriptor(getImageDescriptor("elcl16/refresh_nav.gif"));//$NON-NLS-1$	
+        buildAction = new BuildAction(provider,
+                IncrementalProjectBuilder.INCREMENTAL_BUILD);
+    }
+
+    public void updateActionBars() {
+        IStructuredSelection selection = (IStructuredSelection) getContext()
+                .getSelection();
+        refreshAction.selectionChanged(selection);
+        buildAction.selectionChanged(selection);
+        openProjectAction.selectionChanged(selection);
+        closeUnrelatedProjectsAction.selectionChanged(selection);
+        closeProjectAction.selectionChanged(selection);
+    }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/package.html b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/package.html
new file mode 100644
index 0000000..c0507a1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/package.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides the standard Resource Navigator view which
+presents the tree of resources in the workspace.
+<br>&nbsp;
+</body>
+</html>
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/.classpath b/examples/org.eclipse.e4.ui.examples.css.nebula/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/.project b/examples/org.eclipse.e4.ui.examples.css.nebula/.project
new file mode 100644
index 0000000..6c802f9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.examples.css.nebula</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.ui.examples.css.nebula/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..8a79738
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Jan 28 18:12:20 EST 2009
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.ui.examples.css.nebula/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..48d2d30
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Nebula CSS example (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.examples.css.nebula
+Bundle-Version: 0.9.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.swt;bundle-version="3.5.0",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0",
+ org.eclipse.e4.ui.css.swt;bundle-version="0.9.0",
+ org.eclipse.e4.ui.examples.css;bundle-version="0.9.0",
+ org.eclipse.e4.ui.css.nebula;bundle-version="0.9.0",
+ org.eclipse.nebula.widgets.gallery;bundle-version="1.0.0",
+ org.apache.batik.css;bundle-version="[1.6.0,1.7.0)",
+ org.apache.batik.util;bundle-version="[1.6.0,1.7.0)",
+ org.apache.batik.util.gui;bundle-version="[1.6.0,1.7.0)",
+ org.apache.batik.xml;bundle-version="[1.6.0,1.7.0)"
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/build.properties b/examples/org.eclipse.e4.ui.examples.css.nebula/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/AbstractCSSNebulaEditor.java b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/AbstractCSSNebulaEditor.java
new file mode 100644
index 0000000..b189dd7
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/AbstractCSSNebulaEditor.java
@@ -0,0 +1,30 @@
+package org.eclipse.e4.ui.examples.css.nebula;
+
+import org.eclipse.e4.ui.css.core.dom.IElementProvider;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.dom.NebulaElementProvider;
+import org.eclipse.e4.ui.css.nebula.engine.CSSNebulaEngineImpl;
+import org.eclipse.e4.ui.examples.css.editor.AbstractCSSSWTEditor;
+
+/**
+ * Abstract CSS SWT Editor.
+ */
+public abstract class AbstractCSSNebulaEditor extends AbstractCSSSWTEditor {
+
+	public AbstractCSSNebulaEditor() {
+		super("nebula", null);
+	}
+	
+	protected CSSEngine createCSSEngine() {
+		return new CSSNebulaEngineImpl(shell.getDisplay());
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.e4.ui.core.css.examples.csseditors.AbstractCSSEditor#getNativeWidgetElementProvider()
+	 */
+	protected IElementProvider getNativeWidgetElementProvider() {
+		return NebulaElementProvider.INSTANCE;
+	}
+}
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/CSSEditorNebulaGallery.java b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/CSSEditorNebulaGallery.java
new file mode 100644
index 0000000..8bad973
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/CSSEditorNebulaGallery.java
@@ -0,0 +1,67 @@
+package org.eclipse.e4.ui.examples.css.nebula;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer;
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.Gallery;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+
+public class CSSEditorNebulaGallery extends AbstractCSSNebulaEditor {
+
+	public void createContent(Composite parent) {
+
+		Image itemImage = new Image(parent.getDisplay(), Program.findProgram(
+				"jpg").getImageData());
+		Gallery gallery = new Gallery(parent, SWT.V_SCROLL | SWT.MULTI);
+
+		// Renderers
+		DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer();
+		gr.setMinMargin(2);
+		gr.setItemHeight(56);
+		gr.setItemWidth(72);
+		gr.setAutoMargin(true);
+		gallery.setGroupRenderer(gr);
+
+		DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer();
+		gallery.setItemRenderer(ir);
+
+		int nbGalleryItemSelected = 0;
+		int nbTotalGalleryItemSelected = 2;
+		List selectedItems = new ArrayList();
+
+		for (int g = 0; g < 2; g++) {
+			GalleryItem group = new GalleryItem(gallery, SWT.NONE);
+			group.setText("Group " + g);
+			group.setExpanded(true);
+
+			for (int i = 0; i < 50; i++) {
+				GalleryItem item = new GalleryItem(group, SWT.NONE);
+				if (nbGalleryItemSelected < nbTotalGalleryItemSelected) {
+					nbGalleryItemSelected++;
+					selectedItems.add(item);
+				}
+				if (itemImage != null) {
+					item.setImage(itemImage);
+				}
+				item.setText("Item " + i);
+			}
+		}
+		gallery.setSelection((GalleryItem[]) selectedItems
+				.toArray(new GalleryItem[0]));
+
+		// if (itemImage != null)
+		// itemImage.dispose();
+		// display.dispose();
+	}
+
+	public static void main(String[] args) {
+		CSSEditorNebulaGallery editor = new CSSEditorNebulaGallery();
+		editor.display();
+	}
+}
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/styles/nebula/Gallery.css b/examples/org.eclipse.e4.ui.examples.css.nebula/styles/nebula/Gallery.css
new file mode 100644
index 0000000..27dec93
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/styles/nebula/Gallery.css
@@ -0,0 +1,14 @@
+GalleryItem {
+	color: gray;
+	background-color: #D0D0B0;
+}
+
+GalleryItem:selected {
+	color: purple;	
+    background-color:orange;
+	font:bold;	
+}
+
+Gallery {
+	background-color: #F3F3E3;
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.classpath b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.project b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.project
new file mode 100644
index 0000000..ef93968
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.examples.legacy.workbench</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..58c5f8b
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,108 @@
+#Fri Feb 13 13:56:23 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.launching.prefs b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 0000000..c73f9ad
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+#Fri Feb 13 13:56:23 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..5b675a9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+#Fri Feb 13 13:56:23 EST 2009
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_trailing_whitespaces=false
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_settings_version=11
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************\n * Copyright (c) ${year} IBM Corporation and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n *     IBM Corporation - initial API and implementation\n ******************************************************************************/\n</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.ui.examples.legacy.workbench/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..19c7ef9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.e4.ui.examples.legacy.workbench;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Bundle-Activator: org.eclipse.e4.ui.examples.legacy.workbench.Activator
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.e4.ui.workbench,
+ org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0",
+ org.w3c.css.sac;bundle-version="1.3.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.e4.ui.examples.legacy.workbench
+Import-Package: org.eclipse.e4.core.contexts
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/about.html b/examples/org.eclipse.e4.ui.examples.legacy.workbench/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/build.properties b/examples/org.eclipse.e4.ui.examples.legacy.workbench/build.properties
new file mode 100644
index 0000000..6ee7fb2
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/build.properties
@@ -0,0 +1,29 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               css/,\
+               plugin_customization.ini,\
+               plugin_customization.properties,\
+               eclipse.gif,\
+               eclipse.png,\
+               eclipse24.gif,\
+               eclipse32.gif,\
+               eclipse32.png,\
+               eclipse48.gif,\
+               eclipse48.png,\
+               eclipse_lg.gif,\
+               about.html,\
+               introData.xml,\
+               intro-eclipse.png,\
+               plugin.properties,\
+               splash/,\
+               splash.bmp
+src.includes = src/,\
+               plugin.xml,\
+               about.html,\
+               css/,\
+               p2.inf,\
+               legacy-eclipse.product,\
+               plugin.properties
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css
new file mode 100644
index 0000000..4660676
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css
@@ -0,0 +1,87 @@
+ETabFolder {
+	background-color: rgb(246, 246, 251);
+	simple: true;
+	maximize-visible: false;
+	minimize-visible: false;
+	webby-style: true;
+	margin: 2px;	
+	tab-margin-offset: 4px;
+	
+	border-color: rgb(201, 200, 204)
+/* Can be expressed individually
+	border-top-color: rgb(201, 200, 204);
+	border-bottom-color: rgb(201, 200, 204);
+*/	
+}
+
+ETabFolder.active {
+	background-color: rgb(224, 226, 235);
+}
+   
+ETabItem {
+	color: black;
+	background-color: rgb(241, 240, 245);  /* unselected tabs can have diff color than folder background */
+	padding-top: 4px;
+	padding-bottom: 4px;
+	margin-top: 3px;
+	margin-left: 2px;
+	margin-right: 0px;
+	border-color: rgb(208, 207, 212);
+}
+
+ETabItem:selected {
+	background-color: rgb(255, 255, 255) rgb(246, 245, 250); 
+	padding-top: 7px;  /* make the selected tab a bit taller */
+}
+
+ETabItem.active {
+	background-color: rgb(241, 240, 245);
+}
+
+ETabItem.active:selected {
+	background-color: rgb(255, 255, 255) rgb(255, 247, 229); 
+}
+
+#PerspectiveStack {
+	background-color: rgb(241, 240, 245); 
+	margin: 0px;	
+	tab-margin-offset: 9px;
+}
+
+#PerspectiveStack > ETabItem {
+	background-color: rgb(246, 246, 251);
+	padding-top: 4px;
+	padding-bottom: 2px;
+	margin-top: 0px;
+}
+
+#PerspectiveStack > ETabItem:selected {
+	margin-top: 0px;
+}
+
+#PerspectiveStack > ETabItem.active {
+	background-color: rgb(241, 240, 245); 
+}
+
+#PerspectiveStack > ETabItem.active:selected {
+	background-color: rgb(255, 255, 255) rgb(246, 245, 250); 
+}
+
+.perspectiveLayout, .marginWrapper {
+	background-color: rgb(241, 240, 245); 
+}
+
+ToolBar.inactive {
+	background-color: rgb(246, 246, 251);
+}
+
+ToolBar.active {
+	background-color: rgb(224, 226, 235);
+}
+
+SashForm {
+	background-color: rgb(241, 240, 245); 
+
+Label {
+	background-color: rgb(246, 246, 251);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/xp-silver-legacy.css b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/xp-silver-legacy.css
new file mode 100644
index 0000000..618dbfd
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/xp-silver-legacy.css
@@ -0,0 +1,31 @@
+CTabFolder {
+	font: Tahoma 8px;
+	color: black;
+	background-color: rgb(224, 223, 227);
+	font: normal;
+	simple: false;
+	maximize-visible: true;
+	minimize-visible: true;
+	tab-height: 20;
+}
+
+CTabFolder:selected {
+	background-color: rgb(254, 254, 254) rgb(224, 223, 227);
+}
+
+CTabFolder.active {
+	background-color: rgb(224, 223, 227);
+}
+
+CTabFolder.active:selected {
+	background-color: rgb(237, 237, 237) rgb(192, 192, 192);
+	font: bold;
+}
+
+Text {
+	font: "Courier-New" 10px;
+}      
+
+ToolBar {
+	background-color: rgb(224, 223, 227);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif
new file mode 100644
index 0000000..7d7e32b
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.png
new file mode 100644
index 0000000..25e3bb5
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse24.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse24.gif
new file mode 100644
index 0000000..24296ac
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse24.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif
new file mode 100644
index 0000000..e6ad7cc
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.png
new file mode 100644
index 0000000..568fac1
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif
new file mode 100644
index 0000000..80a40d6
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.png
new file mode 100644
index 0000000..1c939c8
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif
new file mode 100644
index 0000000..bf8b872
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/intro-eclipse.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/intro-eclipse.png
new file mode 100644
index 0000000..015e7fc
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/intro-eclipse.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/introData.xml b/examples/org.eclipse.e4.ui.examples.legacy.workbench/introData.xml
new file mode 100644
index 0000000..2b1c002
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/introData.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<extensions>
+   <page id="tutorials">
+      <group path="page-content/bottom-left" default="true">
+      </group>
+      <group path="page-content/bottom-right" default="true">
+      </group>
+      <group path="page-content/top-left">
+         <extension id="org.eclipse.jdt" importance="low"/>
+         <extension id="org.eclipse.team" importance="low"/>
+      </group>
+      <group path="page-content/top-right">
+         <extension id="org.eclipse.pde" importance="low"/>
+      </group>
+   </page>
+   <page id="whatsnew">
+      <group path="page-content/bottom-left" default="true">
+      </group>
+      <group path="page-content/bottom-right" default="true">
+      </group>
+      <group path="page-content/top-left">
+         <extension id="org.eclipse.ui.workbench.news" importance="low"/>
+         <extension id="org.eclipse.jdt" importance="low"/>
+         <extension id="org.eclipse.pde.changes" importance="low"/>
+         <extension id="org.eclipse.ui.workbench.migration" importance="callout"/>
+      </group>
+      <group path="page-content/top-right">
+         <extension id="org.eclipse.ui.workbench" importance="low"/>
+      </group>
+   </page>
+   <page id="samples">
+      <group path="page-content/bottom-left" default="true">
+      </group>
+      <group path="page-content/bottom-right" default="true">
+      </group>
+      <group path="page-content/top-left">
+         <extension id="org.eclipse.pde.workbench" importance="low"/>
+      </group>
+      <group path="page-content/top-right">
+         <extension id="org.eclipse.jdt" importance="low"/>
+         <extension id="org.eclipse.pde.swt" importance="low"/>
+      </group>
+   </page>
+   <page id="overview">
+      <group path="page-content/bottom-left" default="true">
+      </group>
+      <group path="page-content/bottom-right" default="true">
+      </group>
+      <group path="page-content/top-left">
+         <extension id="org.eclipse.ui.workbench" importance="low"/>
+      </group>
+      <group path="page-content/top-right">
+         <extension id="org.eclipse.jdt" importance="low"/>
+         <extension id="org.eclipse.pde" importance="low"/>
+      </group>
+   </page>
+</extensions>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/legacy-eclipse.product b/examples/org.eclipse.e4.ui.examples.legacy.workbench/legacy-eclipse.product
new file mode 100644
index 0000000..00d732d
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/legacy-eclipse.product
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="e4 SDK" uid="org.eclipse.e4.workbench.sdk" id="org.eclipse.e4.ui.examples.legacy.workbench.product" version="0.9.0.@qualifier@" useFeatures="true" includeLaunchers="true">
+
+   <aboutInfo>
+      <image path="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif"/>
+   </aboutInfo>
+
+   <configIni use="default">
+   </configIni>
+
+   <launcherArgs>
+      <programArgs>--launcher.XXMaxPermSize 256m</programArgs>
+      <vmArgs>-Xms256m -Xmx512m</vmArgs>
+      <vmArgsMac>-Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+   </launcherArgs>
+
+   <windowImages i16="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif" i32="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif" i48="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif"/>
+
+   <splash
+      location="org.eclipse.e4.ui.examples.legacy.workbench" />
+   <launcher name="eclipse">
+      <solaris/>
+      <win useIco="false">
+         <bmp/>
+      </win>
+   </launcher>
+
+   <vm>
+   </vm>
+
+   <plugins>
+   </plugins>
+
+   <features>
+      <feature id="org.eclipse.sdk" version="0.0.0"/>
+      <feature id="org.eclipse.equinox.p2.user.ui" version="0.0.0"/>
+      <feature id="org.eclipse.equinox.p2.user.ui.source" version="0.0.0"/>
+      <feature id="org.eclipse.emf.sdk" version="0.0.0"/>
+      <feature id="org.eclipse.wst.xml_ui.feature" version="0.0.0"/>
+      <feature id="org.eclipse.gef" version="0.0.0"/>
+      <feature id="org.eclipse.rcp.configuration" version="0.0.0"/>
+      <feature id="org.eclipse.e4.sdk.runtime.feature" version="0.0.0"/>
+      <feature id="org.eclipse.e4.sdk.source.feature" version="0.0.0"/>
+      <feature id="org.eclipse.releng.tools" version="0.0.0"/>
+   </features>
+
+   <configurations>
+      <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="4" />
+      <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
+      <plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="2" />
+      <plugin id="org.eclipse.equinox.p2.reconciler.dropins" autoStart="true" startLevel="4" />
+      <plugin id="org.eclipse.equinox.simpleconfigurator" autoStart="true" startLevel="1" />
+      <plugin id="org.eclipse.update.configurator" autoStart="true" startLevel="3" />
+      <property name="eclipse.buildId" value="@qualifier@"/>
+   </configurations>
+
+</product>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/p2.inf b/examples/org.eclipse.e4.ui.examples.legacy.workbench/p2.inf
new file mode 100644
index 0000000..9843e61
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/p2.inf
@@ -0,0 +1,60 @@
+instructions.configure=\
+addRepository(type:0,location:http${#58}//download.eclipse.org/eclipse/updates/3.6-I-builds,name:Eclipse 3.6 I-builds);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/eclipse/updates/3.6-I-builds,name:Eclipse 3.6 I-builds);\
+addRepository(type:0,location:http${#58}//download.eclipse.org/modeling/emf/updates/interim,name:EMF I-builds);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/modeling/emf/updates/interim,name:EMF I-builds);\
+addRepository(type:0,location:http${#58}//download.eclipse.org/tools/gef/updates/interim,name:GEF I-builds);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/tools/gef/updates/interim,name:GEF I-builds);\
+addRepository(type:0,location:http${#58}//download.eclipse.org/webtools/downloads/drops/R3.2/S-3.2.0M2-20090924194346/updateSite,name:WTP R3.2 update site);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/webtools/downloads/drops/R3.2/S-3.2.0M2-20090924194346/updateSite,name:WTP R3.2 update site);\
+  mkdir(path:${installFolder}/dropins);
+requires.1.namespace=org.eclipse.equinox.p2.iu
+requires.1.name=toolingorg.eclipse.configuration.macosx
+requires.1.filter=(osgi.os=macosx)
+requires.1.range=[1.0.0,1.0.0]
+requires.1.greedy=true
+
+requires.2.namespace=org.eclipse.equinox.p2.iu
+requires.2.name=toolingorg.eclipse.configuration
+requires.2.filter=(!(osgi.os=macosx))
+requires.2.range=[1.0.0,1.0.0]
+requires.2.greedy=true
+
+requires.3.namespace=org.eclipse.equinox.p2.iu
+requires.3.name=toolingorg.eclipse.configuration.macosx.x86_64
+requires.3.filter=(&(osgi.os=macosx) (osgi.arch=x86_64))
+requires.3.range=[1.0.0,1.0.0]
+requires.3.greedy=true
+
+units.1.id=toolingorg.eclipse.configuration.macosx
+units.1.version=1.0.0
+units.1.provides.1.namespace=org.eclipse.equinox.p2.iu
+units.1.provides.1.name=toolingorg.eclipse.configuration.macosx
+units.1.provides.1.version=1.0.0
+units.1.filter=(osgi.os=macosx)
+units.1.touchpoint.id=org.eclipse.equinox.p2.osgi
+units.1.touchpoint.version=1.0.0
+units.1.instructions.configure=setProgramProperty(propName:osgi.instance.area.default,propValue:@user.home/Documents/workspace);
+units.1.instructions.unconfigure=setProgramProperty(propName:osgi.instance.area.default,propValue:);
+
+units.2.id=toolingorg.eclipse.configuration
+units.2.version=1.0.0
+units.2.provides.1.namespace=org.eclipse.equinox.p2.iu
+units.2.provides.1.name=toolingorg.eclipse.configuration
+units.2.provides.1.version=1.0.0
+units.2.filter=(!(osgi.os=macosx))
+units.2.touchpoint.id=org.eclipse.equinox.p2.osgi
+units.2.touchpoint.version=1.0.0
+units.2.instructions.configure=setProgramProperty(propName:osgi.instance.area.default,propValue:@user.home/workspace);
+units.2.instructions.unconfigure=setProgramProperty(propName:osgi.instance.area.default,propValue:);
+
+units.3.id=toolingorg.eclipse.configuration.macosx.x86_64
+units.3.version=1.0.0
+units.3.provides.1.namespace=org.eclipse.equinox.p2.iu
+units.3.provides.1.name=toolingorg.eclipse.configuration.macosx.x86_64
+units.3.provides.1.version=1.0.0
+units.3.filter=(&(osgi.os=macosx) (osgi.arch=x86_64))
+units.3.touchpoint.id=org.eclipse.equinox.p2.osgi
+units.3.touchpoint.version=1.0.0
+units.3.instructions.configure=addJvmArg(jvmArg:-Xms40m);addJvmArg(jvmArg:-Xmx512m);
+units.3.instructions.unconfigure=removeJvmArg(jvmArg:-Xms40m);removeJvmArg(jvmArg:-Xmx512m);
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.properties b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.properties
new file mode 100644
index 0000000..31761b1
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.properties
@@ -0,0 +1,27 @@
+pluginName=Eclipse e4 SDK (Incubation)
+providerName=Eclipse.org
+
+productName=e4 SDK
+productBlurb=e4 SDK\n\
+\n\
+Version: July 2010\n\
+Build id: {0}\n\
+\n\
+(c) Copyright Eclipse contributors and others 2000, 2010.  All rights reserved.\n\
+Visit http://www.eclipse.org/e4\n\
+\n\
+This product includes software developed by the\n\
+Apache Software Foundation http://www.apache.org/
+
+productIntroTitle = Welcome to e4
+productIntroBrandingText = Eclipse  Project
+introDescription-overview = The e4 SDK includes all the software required to develop and run
+experimental technology from the e4 incubator
+introDescription-tutorials = Learn how to be productive using Eclipse by completing end-to-end tutorials that will guide you along the way.
+introDescription-samples = Explore Eclipse by installing prefabricated samples (may require Internet connection).
+
+shortcut.overview.tooltip = Overview
+shortcut.tutorials.tooltip = Tutorials
+shortcut.samples.tooltip = Samples
+shortcut.whatsnew.tooltip = What's New
+
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.xml b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.xml
new file mode 100644
index 0000000..7c36626
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.perspectives">
+      <perspective
+            class="org.eclipse.e4.ui.examples.legacy.workbench.TestPerspectiveFactory"
+            id="org.eclipse.e4.ui.examples.legacy.workbench.perspective"
+            name="Legacy Perspective">
+      </perspective>
+   </extension>
+   <extension
+         id="product"
+         point="org.eclipse.core.runtime.products">
+      <product
+            application="org.eclipse.ui.ide.workbench"
+            name="e4 Compatibility Platform">
+          <property name="windowImages" value="eclipse.gif,eclipse32.gif,eclipse48.gif"/> 
+          <property name="aboutImage" value="eclipse_lg.gif"/> 
+         <property
+               name="appName"
+               value="e4 Compatibility Platform">
+         </property>
+         <property
+               name="preferenceCustomization"
+               value="plugin_customization.ini">
+         </property>
+         <property
+               name="applicationCSS"
+               value="platform:/plugin/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css">
+         </property>
+         <property
+          		name="introTitle"
+          		value="%productIntroTitle"/>
+          <property
+          		name="introBrandingImage"
+          		value="product:intro-eclipse.png"/>
+          <property
+          		name="introBrandingImageText"
+          		value="%productIntroBrandingText"/>
+		  <property
+				name="introDescription-overview"
+				value="%introDescription-overview"/>
+		  <property
+				name="introDescription-tutorials"
+				value="%introDescription-tutorials"/>
+		  <property
+				name="introDescription-samples"
+				value="%introDescription-samples"/>
+    <property
+          name="aboutText"
+          value="%productBlurb">
+    </property>                
+      </product>
+   </extension>
+   	<extension
+		point="org.eclipse.ui.intro">
+      <introProductBinding
+            introId="org.eclipse.ui.intro.universal"
+            productId="org.eclipse.e4.ui.examples.legacy.workbench.product">
+      </introProductBinding>
+    </extension>
+    <extension
+          point="org.eclipse.ui.splashHandlers">
+       <splashHandler
+             class="org.eclipse.e4.ui.examples.legacy.workbench.AnimationSplashHandler"
+             id="org.eclipse.e4.ui.examples.legacy.workbench.splashHandlers.browser">
+       </splashHandler>
+    </extension>
+</plugin>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.ini b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.ini
new file mode 100644
index 0000000..5f74564
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.ini
@@ -0,0 +1,41 @@
+# plugin_customization.ini 
+# sets default values for plug-in-specific preferences
+# keys are qualified by plug-in id
+# e.g., com.example.acmeplugin/myproperty=myvalue
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in plugin_customization.properties
+# This file does not need to be translated.
+
+# Property "org.eclipse.ui/defaultPerspectiveId" controls the 
+# perspective that the workbench opens initially
+org.eclipse.ui/defaultPerspectiveId=org.eclipse.jdt.ui.JavaPerspective
+#org.eclipse.ui/defaultPerspectiveId=org.eclipse.e4.ui.examples.legacy.workbench.perspective
+
+# new-style tabs by default
+org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=false
+
+# put the perspective switcher on the top right
+org.eclipse.ui/DOCK_PERSPECTIVE_BAR=topRight
+
+# show progress on startup
+org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = false
+
+# show build id in the splash - only for nightly, integration, and milestone builds
+org.eclipse.ui.workbench/SHOW_BUILDID_ON_STARTUP=true
+
+# use the window set by default
+org.eclipse.ui/USE_WINDOW_WORKING_SET_BY_DEFAULT=true
+
+# Intro-related preferences (since 3.2)
+
+# Welcome theme to use
+org.eclipse.ui.intro/INTRO_THEME = org.eclipse.ui.intro.universal.slate
+
+# Root page links to show in the Universal Welcome
+org.eclipse.ui.intro.universal/INTRO_ROOT_PAGES = overview,tutorials,samples,whatsnew
+
+# Initial page layout of the Universal Welcome
+org.eclipse.ui.intro.universal/INTRO_DATA = product:introData.xml
+
+# Order help books in table of contents
+org.eclipse.help/HELP_DATA = helpData.xml
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.properties b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.properties
new file mode 100644
index 0000000..4943101
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# plugin_customization.properties
+# contains externalized strings for plugin_customization.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash.bmp b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash.bmp
new file mode 100644
index 0000000..ac8039e
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash.bmp
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-dark.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-dark.png
new file mode 100644
index 0000000..65fd673
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-dark.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-light.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-light.png
new file mode 100644
index 0000000..8a8f43c
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-light.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/Activator.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/Activator.java
new file mode 100644
index 0000000..b2cdf36
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/Activator.java
@@ -0,0 +1,49 @@
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import org.osgi.framework.BundleActivator;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+	// The bundle id
+	public static final String BUNDLE_ID = "org.eclipse.e4.ui.examples.legacy.workbench"; //$NON-NLS-1$
+
+	// The shared instance
+	private static BundleContext context;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext aContext) throws Exception {
+		context = aContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext aContext) throws Exception {
+		context = null;
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static BundleContext getContext() {
+		return context;
+	}
+
+}
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/AnimationSplashHandler.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/AnimationSplashHandler.java
new file mode 100644
index 0000000..8de17b9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/AnimationSplashHandler.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Benjamin Cabe and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Benjamin Cabe - initial API and implementation
+ *     IBM Corporation - ongoing development
+ *******************************************************************************/
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.splash.AbstractSplashHandler;
+
+/**
+ *
+ */
+public class AnimationSplashHandler extends AbstractSplashHandler {
+	
+	private final class BundleProgressMonitor extends NullProgressMonitor {
+		private static final int NB_TICKS = 42;
+		private int worked = 0 ;
+		private int total = 0 ;
+		
+		public void worked(int work) {
+			worked++ ;	
+			updateProgressBar();
+		}
+
+		public void done() {
+			worked = total ;
+			updateProgressBar();
+		}
+
+		public void beginTask(String name, int totalWork) {
+			// there are exactly 19 bundles being loaded in the legacy workbench as of 20090722
+			// thus, we prefer to use an hardcoded value for the "length" of the monitor, instead of relying 
+			// on the arbitrary rule assuming there are 1/10 of the installed bundles which are actually loaded
+			total = 19 ; // total = totalWork ;	
+			updateProgressBar();
+		}
+
+		private void updateProgressBar() {
+			int currentImgIdx = (int) (NB_TICKS / (float)total  * worked) ;
+			for (int i = 0 ; i < NB_TICKS ; i++) {
+				Image imgToDraw = (i <= currentImgIdx) ? imgProgressDark : imgProgressLight ;
+				synchronized (shellGC) {
+					shellGC.drawImage(imgToDraw, 11 + (11 * i), 292);
+				}
+			}
+		}
+	}
+
+	private Image imgProgressDark = null;
+	private Image imgProgressLight = null;
+
+	private GC shellGC;
+
+	/**
+	 * 
+	 */
+	public AnimationSplashHandler() {
+		super();
+	}
+
+	private void configureUISplash() {
+		getSplash().setSize(480, 320);
+		getSplash().setVisible(true);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.internal.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell,
+	 *      org.eclipse.ui.IWorkbench)
+	 */
+	public void init(final Shell splash) {
+		// Store the shell
+		super.init(splash);
+		// Load image sequence
+		loadImages();
+		// Configure the shell layout
+		configureUISplash();
+		// Force the UI to layout
+		splash.layout(true);
+		// create the GC we will draw on
+		shellGC = new GC(getSplash());
+	}
+
+	private void loadImages() {
+		ImageLoader loader = new ImageLoader();
+		
+		try {
+			ImageData imageDataProgressDark = loader.load(Activator.getContext().getBundle().getEntry("splash/progress-dark.png").openStream())[0];//$NON-NLS-1$
+			ImageData imageDataProgressLight = loader.load(Activator.getContext().getBundle().getEntry("splash/progress-light.png").openStream())[0]; //$NON-NLS-1$
+			
+			imgProgressDark = new Image(getSplash().getDisplay(), imageDataProgressDark) ;
+			imgProgressLight = new Image(getSplash().getDisplay(), imageDataProgressLight) ;
+		} catch (IOException e1) {
+		}
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.splash.AbstractSplashHandler#getBundleProgressMonitor()
+	 */
+	@Override
+	public IProgressMonitor getBundleProgressMonitor() {
+		return new BundleProgressMonitor();
+	}	
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.splash.AbstractSplashHandler#dispose()
+	 */
+	public void dispose() {
+		if (shellGC != null) {
+			synchronized (shellGC) {
+				shellGC.dispose();
+			}
+		}
+		if (imgProgressDark != null)
+			imgProgressDark.dispose() ;
+		if (imgProgressLight != null)
+			imgProgressLight.dispose() ;
+		
+		super.dispose();
+	}
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/TestPerspectiveFactory.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/TestPerspectiveFactory.java
new file mode 100755
index 0000000..4b84a00
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/TestPerspectiveFactory.java
@@ -0,0 +1,86 @@
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class TestPerspectiveFactory implements IPerspectiveFactory {
+
+	public void createInitialLayout(IPageLayout layout) {
+ 		String editorArea = layout.getEditorArea();
+
+		IFolderLayout folder= layout.createFolder("left", IPageLayout.LEFT, (float)0.25, editorArea); //$NON-NLS-1$
+		//folder.addView("org.eclipse.jdt.ui.PackageExplorer"); //$NON-NLS-1$
+		//folder.addView("org.eclipse.jdt.ui.TypeHierarchy"); //$NON-NLS-1$
+//		folder.addView("LegacyViews.ResourceView"); //$NON-NLS-1$
+		//folder.addPlaceholder(IPageLayout.ID_RES_NAV);
+		folder.addPlaceholder("org.eclipse.ui.navigator.ProjectExplorer"); //$NON-NLS-1$
+
+		IFolderLayout outputfolder= layout.createFolder("bottom", IPageLayout.BOTTOM, (float)0.75, editorArea); //$NON-NLS-1$
+		outputfolder.addView(IPageLayout.ID_PROBLEM_VIEW);
+		outputfolder.addView("org.eclipse.jdt.ui.JavadocView"); //$NON-NLS-1$
+		outputfolder.addView("org.eclipse.team.ccvs.ui.RepositoriesView"); //$NON-NLS-1$
+		outputfolder.addView("org.eclipse.debug.ui.DebugView"); //$NON-NLS-1$
+		outputfolder.addView("org.eclipse.debug.ui.BreakpointView"); //$NON-NLS-1$
+//		outputfolder.addView("org.eclipse.jdt.ui.SourceView"); //$NON-NLS-1$
+//		outputfolder.addPlaceholder("org.eclipse.search.ui.views.SearchView"); //$NON-NLS-1$
+		outputfolder.addPlaceholder("org.eclipse.ui.console.ConsoleView"); //$NON-NLS-1$
+		outputfolder.addView("org.eclipse.pde.runtime.LogView"); //$NON-NLS-1$
+//		outputfolder.addPlaceholder(IPageLayout.ID_BOOKMARKS);
+		outputfolder.addPlaceholder("org.eclipse.ui.views.ProgressView"); //$NON-NLS-1$
+//
+		
+//		IFolderLayout outlineFolder = layout.createFolder("right", IPageLayout.RIGHT, (float)0.75, editorArea); //$NON-NLS-1$
+//		outlineFolder.addView("platform:/plugin/org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView"); //$NON-NLS-1$
+//		IFolderLayout rightFolder = layout.createFolder("right", IPageLayout.RIGHT, (float)0.75, editorArea); //$NON-NLS-1$
+//		rightFolder.addView("platform:/plugin/org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ModelView"); //$NON-NLS-1$
+
+//		outlineFolder.addView(IPageLayout.ID_OUTLINE);
+//
+//		outlineFolder.addPlaceholder("org.eclipse.ui.texteditor.TemplatesView");
+//		// XXX: in 3.4 M7 to be replaced by:
+////		outlineFolder.addView(TemplatesView.ID);
+//
+//		layout.addActionSet("org.eclipse.debug.ui.launchActionSet");
+//		layout.addActionSet("org.eclipse.jdt.ui.JavaActionSet");
+//		layout.addActionSet("org.eclipse.jdt.ui.JavaElementCreationActionSet");
+//		layout.addActionSet(IPageLayout.ID_NAVIGATE_ACTION_SET);
+//
+//		// views - java
+//		layout.addShowViewShortcut("org.eclipse.jdt.ui.PackageExplorer");
+//		layout.addShowViewShortcut("org.eclipse.jdt.ui.TypeHierarchy");
+//		layout.addShowViewShortcut("org.eclipse.jdt.ui.SourceView");
+//		layout.addShowViewShortcut("org.eclipse.jdt.ui.JavadocView");
+//
+//
+//		// views - search
+//		layout.addShowViewShortcut("org.eclipse.search.ui.views.SearchView");
+//
+//		// views - debugging
+//		layout.addShowViewShortcut("org.eclipse.ui.console.ConsoleView");
+//
+//		// views - standard workbench
+//		layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
+//		layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
+//		layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
+//		layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
+//		layout.addShowViewShortcut("org.eclipse.ui.views.ProgressView");
+//		layout.addShowViewShortcut("org.eclipse.ui.navigator.ProjectExplorer");
+//		layout.addShowViewShortcut("org.eclipse.ui.texteditor.TemplatesView");
+//
+//		// new actions - Java project creation wizard
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.JavaProjectWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewPackageCreationWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewClassCreationWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewEnumCreationWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard");	 //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard"); //$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder");//$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");//$NON-NLS-1$
+//		layout.addNewWizardShortcut("org.eclipse.ui.editors.wizards.UntitledTextFileWizard");//$NON-NLS-1$
+	}
+
+}
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/WorkspaceValue.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/WorkspaceValue.java
new file mode 100644
index 0000000..6fc0bf7
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/WorkspaceValue.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.e4.core.contexts.IContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+
+public class WorkspaceValue implements IContextFunction {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.e4.core.contexts.IContextFunction#compute(org.eclipse.e4.core.contexts.IEclipseContext)
+	 */
+	public Object compute(IEclipseContext context) {
+		ResourcesPlugin.getPlugin().getPluginPreferences().setValue(ResourcesPlugin.PREF_AUTO_REFRESH, true);
+		return ResourcesPlugin.getWorkspace();
+	}
+
+}
diff --git a/features/.gitignore b/features/.gitignore
new file mode 100644
index 0000000..d8fe4fa
--- /dev/null
+++ b/features/.gitignore
@@ -0,0 +1 @@
+/.project
diff --git a/features/org.eclipse.e4.master/.project b/features/org.eclipse.e4.master/.project
new file mode 100644
index 0000000..9bf17ac
--- /dev/null
+++ b/features/org.eclipse.e4.master/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.master</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.master/build.properties b/features/org.eclipse.e4.master/build.properties
new file mode 100644
index 0000000..18c0521
--- /dev/null
+++ b/features/org.eclipse.e4.master/build.properties
@@ -0,0 +1,5 @@
+bin.includes = feature.xml,\
+               feature.properties
+
+generate.feature@org.eclipse.e4.swt.as.source.feature=org.eclipse.e4.swt.as.feature
+
diff --git a/features/org.eclipse.e4.master/feature.properties b/features/org.eclipse.e4.master/feature.properties
new file mode 100644
index 0000000..c527e56
--- /dev/null
+++ b/features/org.eclipse.e4.master/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Master Build Feature (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 Master Build Feature
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.master/feature.xml b/features/org.eclipse.e4.master/feature.xml
new file mode 100644
index 0000000..931f293
--- /dev/null
+++ b/features/org.eclipse.e4.master/feature.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.master"
+      label="%featureName"
+      version="0.11.0.qualifier"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <includes
+         id="org.eclipse.e4.ui.examples.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.ui.tests.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.tests.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.tm.tests.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.tests.base.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.sdk.runtime.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.sdk.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.resources.tests.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.platform.discovery.master"
+         version="0.0.0"/>
+         
+   <includes
+         id="org.eclipse.e4.tools.e3x.bridge.feature"
+         version="0.0.0"/>
+         
+   <includes
+         id="org.eclipse.e4.tools.css.editor.feature"
+         version="0.0.0"/>
+         
+   <includes
+         id="org.eclipse.e4.tools.css.spy.feature"
+         version="0.0.0"/>
+         
+</feature>
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/.project b/features/org.eclipse.e4.sdk.runtime.feature/.project
new file mode 100644
index 0000000..426d87f
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.sdk.runtime.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/build.properties b/features/org.eclipse.e4.sdk.runtime.feature/build.properties
new file mode 100755
index 0000000..f12f4e5
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/build.properties
@@ -0,0 +1,3 @@
+bin.includes = feature.xml,\
+               feature.properties
+
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/feature.properties b/features/org.eclipse.e4.sdk.runtime.feature/feature.properties
new file mode 100644
index 0000000..14562f3
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 SDK runtime (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Includes all of the e4 features to build an SDK
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/feature.xml b/features/org.eclipse.e4.sdk.runtime.feature/feature.xml
new file mode 100755
index 0000000..35a37e6
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/feature.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.sdk.runtime.feature"
+      label="%featureName"
+      version="0.11.0.qualifier"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <includes
+         id="org.eclipse.e4.ui.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.ui.css.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.tools.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.ui.compatibility.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.runtime.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.server.bespin.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.css.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.tm.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.emf.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.workbench.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.resources.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.core.tools.feature"
+         version="0.0.0"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.sdk.source.feature/.project b/features/org.eclipse.e4.sdk.source.feature/.project
new file mode 100644
index 0000000..77ce76f
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.sdk.source.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.sdk.source.feature/build.properties b/features/org.eclipse.e4.sdk.source.feature/build.properties
new file mode 100755
index 0000000..b9a9a08
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/build.properties
@@ -0,0 +1,19 @@
+bin.includes = feature.xml,\
+               feature.properties
+
+generate.feature@org.eclipse.e4.ui.source.feature=org.eclipse.e4.ui.feature,plugin@javax.inject.source;unpack="false",plugin@javax.annotation.source;unpack="false"
+generate.feature@org.eclipse.e4.ui.compatibility.source.feature=org.eclipse.e4.ui.compatibility.feature
+generate.feature@org.eclipse.e4.ui.css.source.feature=org.eclipse.e4.ui.css.feature
+generate.feature@org.eclipse.e4.xwt.source.feature=org.eclipse.e4.xwt.feature
+generate.feature@org.eclipse.e4.xwt.tools.source.feature=org.eclipse.e4.xwt.tools.feature
+generate.feature@org.eclipse.e4.languages.source.feature=org.eclipse.e4.languages.feature,plugin@org.eclipse.wst.jsdt.core.source;unpack="false",plugin@org.eclipse.wst.jsdt.manipulation.source;unpack="false",plugin@org.eclipse.wst.jsdt.ui.source;unpack="false",plugin@org.mozilla.javascript.source;unpack="false"
+generate.feature@org.eclipse.e4.server.bespin.source.feature=org.eclipse.e4.server.bespin.feature
+generate.feature@org.eclipse.e4.xwt.css.source.feature=org.eclipse.e4.xwt.css.feature
+generate.feature@org.eclipse.e4.xwt.emf.source.feature=org.eclipse.e4.xwt.emf.feature
+generate.feature@org.eclipse.e4.xwt.workbench.source.feature=org.eclipse.e4.xwt.workbench.feature
+generate.feature@org.eclipse.e4.tm.source.feature=org.eclipse.e4.tm.feature
+generate.feature@org.eclipse.e4.ui.compatibility.source.feature=org.eclipse.e4.ui.compatibility.feature
+generate.feature@org.eclipse.e4.ui.web.source.feature=org.eclipse.e4.ui.web.feature
+generate.feature@org.eclipse.e4.resources.source.feature=org.eclipse.e4.resources.feature
+generate.feature@org.eclipse.e4.core.tools.source.feature=org.eclipse.e4.core.tools.feature
+generate.feature@org.eclipse.e4.tools.e3x.bridge.source.feature=org.eclipse.e4.tools.e3x.bridge.feature
diff --git a/features/org.eclipse.e4.sdk.source.feature/feature.properties b/features/org.eclipse.e4.sdk.source.feature/feature.properties
new file mode 100644
index 0000000..e18b6f8
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 SDK source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Includes all of the source features for the SDK runtime
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.sdk.source.feature/feature.xml b/features/org.eclipse.e4.sdk.source.feature/feature.xml
new file mode 100755
index 0000000..77370f2
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/feature.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.sdk.source.feature"
+      label="%featureName"
+      version="0.12.0.qualifier"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <includes
+         id="org.eclipse.e4.ui.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.ui.css.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.tools.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.ui.compatibility.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.server.bespin.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.css.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.tm.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.emf.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.xwt.workbench.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.ui.web.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.resources.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.core.tools.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.e4.tools.e3x.bridge.source.feature"
+         version="0.0.0"/>
+
+   <includes
+         id="org.eclipse.platform.discovery.source.master"
+         version="0.0.0"/>
+         
+   <requires>
+      <import feature="org.eclipse.e4.sdk.runtime.feature" version="0.9.0" match="compatible"/>
+   </requires>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/.project b/features/org.eclipse.e4.ui.compatibility.feature/.project
new file mode 100644
index 0000000..61d873c
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.compatibility.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/build.properties b/features/org.eclipse.e4.ui.compatibility.feature/build.properties
new file mode 100644
index 0000000..f12f4e5
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/build.properties
@@ -0,0 +1,3 @@
+bin.includes = feature.xml,\
+               feature.properties
+
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/feature.properties b/features/org.eclipse.e4.ui.compatibility.feature/feature.properties
new file mode 100644
index 0000000..ebf4120
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 UI Compatibility Layer (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 UI Compatibility Layer
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/feature.xml b/features/org.eclipse.e4.ui.compatibility.feature/feature.xml
new file mode 100644
index 0000000..1c416c5
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/feature.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.ui.compatibility.feature"
+      label="%featureName"
+      version="0.9.1.qualifier"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <requires>
+      <import feature="org.eclipse.e4.ui.feature" version="0.9.0" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.e4.ui.examples.legacy.workbench"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.xsd"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.xsd.edit"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.wst.common.project.facet.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+@page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..1f250af
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse E4 UI Compatibility Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+   
+<h3>Applicable Licenses</h3>   
+   
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository (&quot;Repository&quot;) in CVS
+   modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
+   
+<ul>
+	<li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
+	<li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
+	<li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li>
+	<li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
+</ul>   
+ 
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+	<li>The top-level (root) directory</li>
+	<li>Plug-in and Fragment directories</li>
+	<li>Inside Plug-ins and Fragments packaged as JARs</li>
+	<li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
+	<li>Feature directories</li>
+</ul>
+		
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+	<li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+	<li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+	<li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+	<li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>	
+	<li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+	<li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+   
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>   
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..cdb3ab3
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.css.feature/.project b/features/org.eclipse.e4.ui.css.feature/.project
new file mode 100644
index 0000000..eb3439f
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.css.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.css.feature/build.properties b/features/org.eclipse.e4.ui.css.feature/build.properties
new file mode 100644
index 0000000..655791e
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/build.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2010 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = feature.xml,\
+               feature.properties
+
+#generate.feature@org.eclipse.e4.resources.rcp.patch.source = org.eclipse.e4.resources.rcp.patch
+#generate.feature@org.eclipse.e4.resources.platform.patch.source = org.eclipse.e4.resources.platform.patch
diff --git a/features/org.eclipse.e4.ui.css.feature/feature.properties b/features/org.eclipse.e4.ui.css.feature/feature.properties
new file mode 100644
index 0000000..f66fea6
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 CSS Support (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 CSS Support
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.css.feature/feature.xml b/features/org.eclipse.e4.ui.css.feature/feature.xml
new file mode 100644
index 0000000..c0773a0
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/feature.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.ui.css.feature"
+      label="%featureName"
+      version="0.9.1.qualifier"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <plugin
+         id="org.eclipse.e4.ui.css.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.css.jface"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.css.swt"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.apache.batik.css"
+         download-size="0"
+         install-size="0"
+         version="1.6.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.apache.batik.util"
+         download-size="0"
+         install-size="0"
+         version="1.6.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.apache.batik.util.gui"
+         download-size="0"
+         install-size="0"
+         version="1.6.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.apache.batik.xml"
+         download-size="0"
+         install-size="0"
+         version="1.6.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.w3c.css.sac"
+         download-size="0"
+         install-size="0"
+         version="1.3.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.w3c.dom.smil"
+         download-size="0"
+         install-size="0"
+         version="1.0.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.w3c.dom.svg"
+         download-size="0"
+         install-size="0"
+         version="1.1.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.nebula.widgets.gallery"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.css.nebula"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.css.swt.theme"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+@page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..be93723
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse E4 UI CSS Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+   
+<h3>Applicable Licenses</h3>   
+   
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository (&quot;Repository&quot;) in CVS
+   modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
+   
+<ul>
+	<li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
+	<li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
+	<li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li>
+	<li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
+</ul>   
+ 
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+	<li>The top-level (root) directory</li>
+	<li>Plug-in and Fragment directories</li>
+	<li>Inside Plug-ins and Fragments packaged as JARs</li>
+	<li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
+	<li>Feature directories</li>
+</ul>
+		
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+	<li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+	<li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+	<li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+	<li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>	
+	<li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+	<li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+   
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>   
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.css.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..45f08b3
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.examples.feature/.project b/features/org.eclipse.e4.ui.examples.feature/.project
new file mode 100644
index 0000000..4ed0358
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.examples.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.examples.feature/build.properties b/features/org.eclipse.e4.ui.examples.feature/build.properties
new file mode 100644
index 0000000..b3a611b
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/build.properties
@@ -0,0 +1,2 @@
+bin.includes = feature.xml,\
+               feature.properties
diff --git a/features/org.eclipse.e4.ui.examples.feature/feature.properties b/features/org.eclipse.e4.ui.examples.feature/feature.properties
new file mode 100644
index 0000000..b7176f3
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 UI Examples Build feature (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 UI Examples
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2008 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.examples.feature/feature.xml b/features/org.eclipse.e4.ui.examples.feature/feature.xml
new file mode 100644
index 0000000..d785c88
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/feature.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.ui.examples.feature"
+      label="%featureName"
+      version="0.9.0.qualifier"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <requires>
+      <import feature="org.eclipse.e4.ui.feature" version="0.9.0" match="compatible"/>
+      <import feature="org.eclipse.e4.ui.css.feature" version="0.9.0" match="compatible"/>
+      <import feature="org.eclipse.e4.ui.compatibility.feature" version="0.9.0" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.e4.demo.e4photo"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.examples.css"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.examples.css.nebula"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.examples.css.rcp"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+ <!-- Temporarily remove for bug 332576
+   <plugin
+         id="org.eclipse.e4.ui.css.legacy"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+-->
+   <plugin
+         id="org.eclipse.e4.demo.contacts"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.feature/.project b/features/org.eclipse.e4.ui.feature/.project
new file mode 100644
index 0000000..d2c42bf
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.feature/build.properties b/features/org.eclipse.e4.ui.feature/build.properties
new file mode 100644
index 0000000..5aafe93
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/build.properties
@@ -0,0 +1,5 @@
+bin.includes = feature.xml,\
+               feature.properties
+
+#generate.feature@org.eclipse.e4.resources.rcp.patch.source = org.eclipse.e4.resources.rcp.patch
+#generate.feature@org.eclipse.e4.resources.platform.patch.source = org.eclipse.e4.resources.platform.patch
diff --git a/features/org.eclipse.e4.ui.feature/feature.properties b/features/org.eclipse.e4.ui.feature/feature.properties
new file mode 100644
index 0000000..8df942c
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Modeled Workbench (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=The main modeled workbench, SWT renderers, and core services/contexts.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.feature/feature.xml b/features/org.eclipse.e4.ui.feature/feature.xml
new file mode 100644
index 0000000..82a0255
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/feature.xml
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.ui.feature"
+      label="%featureName"
+      version="0.10.0.qualifier"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <includes
+         id="org.eclipse.e4.ui.web.feature"
+         version="0.0.0"/>
+
+   <requires>
+      <import feature="org.eclipse.emf.databinding" version="1.0.0.v200808251517" match="compatible"/>
+      <import feature="org.eclipse.emf.ecore" version="2.4.1.v200808251517" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.e4.core.services"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.model.workbench"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.model.workbench.edit"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.services"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.workbench"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.core.javascript"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.mozilla.javascript"
+         download-size="0"
+         install-size="0"
+         version="1.7.2.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="javax.xml"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.workbench.renderers.swt"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.workbench.addons.swt"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.workbench.swt"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.pde.ui"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.pde.webui"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.dojotoolkit"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.core.commands"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="javax.inject"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="javax.annotation"
+         download-size="0"
+         install-size="0"
+         version="1.0.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.bindings"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.workbench3"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.pushingpixels.trident"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.core.contexts"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.core.contexts.debug"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.core.di"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.core.di.extensions"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.di"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.widgets"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.workbench.renderers.swt.cocoa"
+         os="macosx"
+         ws="cocoa"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         fragment="true"
+         unpack="false"/>
+
+   <plugin
+         id="org.apache.commons.jxpath"
+         download-size="0"
+         install-size="0"
+         version="1.3.0.qualifier"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.emf.xpath"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+@page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..cfedcc8
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Modeled Workbench Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+   
+<h3>Applicable Licenses</h3>   
+   
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository (&quot;Repository&quot;) in CVS
+   modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
+   
+<ul>
+	<li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
+	<li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
+	<li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li>
+	<li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
+</ul>   
+ 
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+	<li>The top-level (root) directory</li>
+	<li>Plug-in and Fragment directories</li>
+	<li>Inside Plug-ins and Fragments packaged as JARs</li>
+	<li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
+	<li>Feature directories</li>
+</ul>
+		
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+	<li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+	<li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+	<li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+	<li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>	
+	<li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+	<li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+   
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>   
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.html b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.html
new file mode 100755
index 0000000..c207d05
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>May 10, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Source Code</h3>
+<p>This plug-in contains source code zip files (&quot;Source Zips&quot;) that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license
+agreements and/or notices. Details about these license agreements and notices are contained in &quot;about.html&quot; files (&quot;Abouts&quot;) located in sub-directories in the
+src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.ini b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.ini
new file mode 100755
index 0000000..5dfa1c0
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.ini
@@ -0,0 +1,29 @@
+# about.ini

+# contains information about a feature

+# java.io.Properties file (ISO 8859-1 with "\" escapes)

+# "%key" are externalized strings defined in about.properties

+# This file does not need to be translated.

+

+# Property "aboutText" contains blurb for "About" dialog (translated)

+aboutText=%blurb

+

+# Property "windowImage" contains path to window icon (16x16)

+# needed for primary features only

+

+# Property "featureImage" contains path to feature image (32x32)

+featureImage=eclipse32.png

+

+# Property "aboutImage" contains path to product image (500x330 or 115x164)

+# needed for primary features only

+

+# Property "appName" contains name of the application (not translated)

+# needed for primary features only

+

+# Property "welcomePage" contains path to welcome page (special XML-based format)

+# optional

+

+# Property "welcomePerspective" contains the id of the perspective in which the

+# welcome page is to be opened.

+# optional

+

+

diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.mappings b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.mappings
new file mode 100755
index 0000000..0dfb735
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.mappings
@@ -0,0 +1,6 @@
+# about.mappings

+# contains fill-ins for about.properties

+# java.io.Properties file (ISO 8859-1 with "\" escapes)

+# This file does not need to be translated.

+

+0=@build@

diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.properties b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.properties
new file mode 100755
index 0000000..8087967
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+
+blurb=Eclipse E4 SDK\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+(c) Copyright Eclipse contributors and others 2000, 2007.  All rights reserved.\n\
+Visit http://wiki.eclipse.org/E4
+
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..df97790
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = about.html, about.ini, about.mappings, about.properties, eclipse32.png, plugin.properties, plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.gif b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.gif
new file mode 100755
index 0000000..e6ad7cc
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.gif
Binary files differ
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.png b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.png
new file mode 100755
index 0000000..568fac1
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.png
Binary files differ
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/plugin.properties b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/plugin.properties
new file mode 100755
index 0000000..625bcdc
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+pluginName=Eclipse E4 SDK
+providerName=Eclipse.org
diff --git a/features/org.eclipse.e4.ui.tests.feature/.project b/features/org.eclipse.e4.ui.tests.feature/.project
new file mode 100644
index 0000000..2695291
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.tests.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.tests.feature/build.properties b/features/org.eclipse.e4.ui.tests.feature/build.properties
new file mode 100644
index 0000000..b3a611b
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/build.properties
@@ -0,0 +1,2 @@
+bin.includes = feature.xml,\
+               feature.properties
diff --git a/features/org.eclipse.e4.ui.tests.feature/feature.properties b/features/org.eclipse.e4.ui.tests.feature/feature.properties
new file mode 100644
index 0000000..e836e78
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Modeled Workbench Tests (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Tests for the modeled workbench
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2008 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.tests.feature/feature.xml b/features/org.eclipse.e4.ui.tests.feature/feature.xml
new file mode 100644
index 0000000..4162d22
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/feature.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.ui.tests.feature"
+      label="%featureName"
+      version="0.9.1.qualifier"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <requires>
+      <import feature="org.eclipse.e4.ui.css.feature" version="0.9.0" match="compatible"/>
+      <import feature="org.eclipse.e4.ui.feature" version="0.9.0" match="compatible"/>
+      <import feature="org.eclipse.e4.tests.base.feature" version="0.9.0" match="compatible"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.e4.ui.tests.css.swt"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.tests.css.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.e4.core.tests.services"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.tests"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.e4.core.commands.tests"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.bindings.tests"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.e4.core.tests"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+
+   <plugin
+         id="com.google.code.atinject.tck"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.menu.tests"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"/>
+         
+    <plugin
+         id="org.eclipse.e4.ui.menu.tests.p1"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+    <plugin
+         id="org.eclipse.e4.ui.menu.tests.p2"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+    <plugin
+         id="org.eclipse.e4.ui.menu.tests.p3"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+    <plugin
+         id="org.eclipse.e4.ui.menu.tests.p4"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+         
+</feature>
diff --git a/features/org.eclipse.e4.ui.web.feature/.project b/features/org.eclipse.e4.ui.web.feature/.project
new file mode 100644
index 0000000..cf972dd
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.web.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.web.feature/build.properties b/features/org.eclipse.e4.ui.web.feature/build.properties
new file mode 100644
index 0000000..b3a611b
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/build.properties
@@ -0,0 +1,2 @@
+bin.includes = feature.xml,\
+               feature.properties
diff --git a/features/org.eclipse.e4.ui.web.feature/feature.properties b/features/org.eclipse.e4.ui.web.feature/feature.properties
new file mode 100755
index 0000000..2f654ba
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2009 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Web Gadget (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Provides web support for views and for loading in Social Gadgets
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.web.feature/feature.xml b/features/org.eclipse.e4.ui.web.feature/feature.xml
new file mode 100644
index 0000000..b739511
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/feature.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.e4.ui.web.feature"
+      label="%featureName"
+      version="0.9.0.qualifier"
+      provider-name="%providerName"
+      image="eclipse_update_120.jpg">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <plugin
+         id="org.eclipse.e4.ui.web"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.e4.ui.gadgets"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+@page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..dbf3795
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Web Gadget Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+   
+<h3>Applicable Licenses</h3>   
+   
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository (&quot;Repository&quot;) in CVS
+   modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
+   
+<ul>
+	<li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
+	<li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
+	<li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li>
+	<li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
+</ul>   
+ 
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+	<li>The top-level (root) directory</li>
+	<li>Plug-in and Fragment directories</li>
+	<li>Inside Plug-ins and Fragments packaged as JARs</li>
+	<li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
+	<li>Feature directories</li>
+</ul>
+		
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+	<li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+	<li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+	<li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+	<li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>	
+	<li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+	<li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+   
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>   
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.html b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.html
new file mode 100755
index 0000000..c207d05
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>May 10, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Source Code</h3>
+<p>This plug-in contains source code zip files (&quot;Source Zips&quot;) that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license
+agreements and/or notices. Details about these license agreements and notices are contained in &quot;about.html&quot; files (&quot;Abouts&quot;) located in sub-directories in the
+src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.ini b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.ini
new file mode 100755
index 0000000..5dfa1c0
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.ini
@@ -0,0 +1,29 @@
+# about.ini

+# contains information about a feature

+# java.io.Properties file (ISO 8859-1 with "\" escapes)

+# "%key" are externalized strings defined in about.properties

+# This file does not need to be translated.

+

+# Property "aboutText" contains blurb for "About" dialog (translated)

+aboutText=%blurb

+

+# Property "windowImage" contains path to window icon (16x16)

+# needed for primary features only

+

+# Property "featureImage" contains path to feature image (32x32)

+featureImage=eclipse32.png

+

+# Property "aboutImage" contains path to product image (500x330 or 115x164)

+# needed for primary features only

+

+# Property "appName" contains name of the application (not translated)

+# needed for primary features only

+

+# Property "welcomePage" contains path to welcome page (special XML-based format)

+# optional

+

+# Property "welcomePerspective" contains the id of the perspective in which the

+# welcome page is to be opened.

+# optional

+

+

diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.mappings b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.mappings
new file mode 100755
index 0000000..0dfb735
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.mappings
@@ -0,0 +1,6 @@
+# about.mappings

+# contains fill-ins for about.properties

+# java.io.Properties file (ISO 8859-1 with "\" escapes)

+# This file does not need to be translated.

+

+0=@build@

diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.properties
new file mode 100755
index 0000000..8087967
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+
+blurb=Eclipse E4 SDK\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+(c) Copyright Eclipse contributors and others 2000, 2007.  All rights reserved.\n\
+Visit http://wiki.eclipse.org/E4
+
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..df97790
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = about.html, about.ini, about.mappings, about.properties, eclipse32.png, plugin.properties, plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.gif b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.gif
new file mode 100755
index 0000000..e6ad7cc
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.gif
Binary files differ
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.png b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.png
new file mode 100755
index 0000000..568fac1
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.png
Binary files differ
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/plugin.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/plugin.properties
new file mode 100755
index 0000000..ca5f27f
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+pluginName=Eclipse e4 Web Gadgets Source
+providerName=Eclipse.org
diff --git a/tests/org.eclipse.e4.ui.selection.tests/.classpath b/tests/org.eclipse.e4.ui.selection.tests/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tests/org.eclipse.e4.ui.selection.tests/.project b/tests/org.eclipse.e4.ui.selection.tests/.project
new file mode 100644
index 0000000..09827d4
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.e4.ui.selection.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tests/org.eclipse.e4.ui.selection.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.e4.ui.selection.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ce20b75
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu Nov 12 13:03:36 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/tests/org.eclipse.e4.ui.selection.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.e4.ui.selection.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..da95fee
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Selection Tests
+Bundle-SymbolicName: org.eclipse.e4.ui.selection.tests
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.e4.ui.selection.tests.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.junit
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.e4.core.services,
+ org.eclipse.e4.core.services.annotations,
+ org.eclipse.e4.core.services.context,
+ org.eclipse.e4.core.services.context.spi,
+ org.eclipse.e4.ui.selection,
+ org.osgi.service.log;version="1.3.0"
diff --git a/tests/org.eclipse.e4.ui.selection.tests/build.properties b/tests/org.eclipse.e4.ui.selection.tests/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/Activator.java b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/Activator.java
new file mode 100644
index 0000000..826d941
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/Activator.java
@@ -0,0 +1,85 @@
+package org.eclipse.e4.ui.selection.tests;
+
+import org.eclipse.e4.core.services.IDisposable;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class Activator implements BundleActivator {
+
+	private static Activator plugin = null;
+	private IEclipseContext appContext;
+	private IEclipseContext serviceContext;
+
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	public void start(BundleContext context) throws Exception {
+		plugin = this;
+		serviceContext = EclipseContextFactory.getServiceContext(context);
+		appContext = EclipseContextFactory.create(serviceContext, null);
+		addLogService(appContext);
+	}
+
+	private void addLogService(IEclipseContext context) {
+		context.set(LogService.class.getName(), new LogService() {
+
+			public void log(int level, String message) {
+				System.out.println(level + ": " + message);
+			}
+
+			public void log(int level, String message, Throwable exception) {
+				System.out.println(level + ": " + message);
+				if (exception != null) {
+					exception.printStackTrace();
+				}
+			}
+
+			public void log(ServiceReference sr, int level, String message) {
+				// TODO Auto-generated method stub
+
+			}
+
+			public void log(ServiceReference sr, int level, String message,
+					Throwable exception) {
+				// TODO Auto-generated method stub
+
+			}
+		});
+	}
+
+	public void stop(BundleContext context) throws Exception {
+		if (serviceContext instanceof IDisposable) {
+			((IDisposable) serviceContext).dispose();
+		}
+		plugin = null;
+	}
+
+	public IEclipseContext getGlobalContext() {
+		return appContext;
+	}
+
+	public PackageAdmin getBundleAdmin() {
+		return (PackageAdmin) serviceContext.get(PackageAdmin.class.getName());
+	}
+
+	public Bundle getBundleForName(String bundleName) {
+		Bundle[] bundles = getBundleAdmin().getBundles(bundleName, null);
+		if (bundles == null)
+			return null;
+		// Return the first bundle that is not installed or uninstalled
+		for (int i = 0; i < bundles.length; i++) {
+			if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
+				return bundles[i];
+			}
+		}
+		return null;
+	}
+}
+
diff --git a/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/SelectionTest.java b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/SelectionTest.java
new file mode 100644
index 0000000..1745714
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/SelectionTest.java
@@ -0,0 +1,245 @@
+package org.eclipse.e4.ui.selection.tests;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import junit.framework.TestCase;
+
+import org.eclipse.e4.core.services.IDisposable;
+import org.eclipse.e4.core.services.annotations.Optional;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextInjectionFactory;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+import org.eclipse.e4.ui.selection.ESelectionService;
+
+public class SelectionTest extends TestCase {
+
+	private static final String SEL_TWO = "two";
+	private static final String SEL_ONE = "one";
+
+	static class ConsumerPart {
+		public String input;
+
+		@Inject
+		@Optional
+		public void setInput(@Named(ESelectionService.SELECTION) String current) {
+			input = current;
+		}
+	}
+
+	static class ProviderPart extends ConsumerPart {
+		private ESelectionService selectionService;
+
+		@Inject
+		public void setSelectionService(ESelectionService s) {
+			selectionService = s;
+		}
+
+		public void setSelection(String s) {
+			selectionService.setSelection(s);
+		}
+	}
+
+	static class TrackingProviderPart extends ProviderPart {
+		public String otherSelection;
+
+		public void setOtherSelection(String s) {
+			otherSelection = s;
+		}
+	}
+
+	private IEclipseContext workbenchContext;
+
+	public void testOnePartSelection() throws Exception {
+		ProviderPart p = new ProviderPart();
+		ContextInjectionFactory.inject(p, workbenchContext);
+
+		assertNull(p.input);
+
+		p.setSelection(SEL_ONE);
+		assertEquals(SEL_ONE, p.input);
+		p.setSelection(null);
+		assertNull(p.input);
+	}
+
+	static class UseSelectionHandler {
+		public String selection;
+
+		public void execute(
+				@Optional @Named(ESelectionService.SELECTION) String s) {
+			selection = s;
+		}
+	}
+
+	public void testTwoPartHandlerExecute() throws Exception {
+		IEclipseContext window = TestUtil.createContext(workbenchContext,
+				"windowContext");
+		workbenchContext.set(IContextConstants.ACTIVE_CHILD, window);
+
+		IEclipseContext partOne = TestUtil.createContext(window, "partOne");
+		window.set(IContextConstants.ACTIVE_CHILD, partOne);
+		ProviderPart partOneImpl = new ProviderPart();
+		ContextInjectionFactory.inject(partOneImpl, partOne);
+
+		IEclipseContext partTwo = TestUtil.createContext(window, "partTwo");
+		ConsumerPart partTwoImpl = new ConsumerPart();
+		ContextInjectionFactory.inject(partTwoImpl, partTwo);
+
+		partOneImpl.setSelection(SEL_ONE);
+
+		UseSelectionHandler handler = new UseSelectionHandler();
+		assertNull(handler.selection);
+
+		ContextInjectionFactory.invoke(handler, "execute", workbenchContext,
+				null);
+		assertEquals(SEL_ONE, handler.selection);
+		ContextInjectionFactory.invoke(handler, "execute", window, null);
+		assertEquals(SEL_ONE, handler.selection);
+		ContextInjectionFactory.invoke(handler, "execute", partOne, null);
+		assertEquals(SEL_ONE, handler.selection);
+		ContextInjectionFactory.invoke(handler, "execute", partTwo, null);
+		assertNull(handler.selection);
+
+		window.set(IContextConstants.ACTIVE_CHILD, partTwo);
+
+		ContextInjectionFactory.invoke(handler, "execute", workbenchContext,
+				null);
+		assertNull(handler.selection);
+		ContextInjectionFactory.invoke(handler, "execute", window, null);
+		assertNull(handler.selection);
+		ContextInjectionFactory.invoke(handler, "execute", partOne, null);
+		assertEquals(SEL_ONE, handler.selection);
+		ContextInjectionFactory.invoke(handler, "execute", partTwo, null);
+		assertNull(handler.selection);
+	}
+
+	public void testThreePartSelection() throws Exception {
+		ESelectionService workbenchService = (ESelectionService) workbenchContext
+				.get(ESelectionService.class.getName());
+		IEclipseContext window = TestUtil.createContext(workbenchContext,
+				"windowContext");
+		workbenchContext.set(IContextConstants.ACTIVE_CHILD, window);
+		ESelectionService windowService = (ESelectionService) window
+				.get(ESelectionService.class.getName());
+
+		IEclipseContext partOne = TestUtil.createContext(window, "partOne");
+		window.set(IContextConstants.ACTIVE_CHILD, partOne);
+		ProviderPart partOneImpl = new ProviderPart();
+		ContextInjectionFactory.inject(partOneImpl, partOne);
+
+		IEclipseContext partTwo = TestUtil.createContext(window, "partTwo");
+		ConsumerPart partTwoImpl = new ConsumerPart();
+		ContextInjectionFactory.inject(partTwoImpl, partTwo);
+
+		IEclipseContext partThree = TestUtil.createContext(window, "partThree");
+		ProviderPart partThreeImpl = new ProviderPart();
+		ContextInjectionFactory.inject(partThreeImpl, partThree);
+
+		assertNull(workbenchService.getSelection());
+		assertNull(windowService.getSelection());
+		assertNull(partOneImpl.input);
+		assertNull(partTwoImpl.input);
+		assertNull(partThreeImpl.input);
+
+		partOneImpl.setSelection(SEL_ONE);
+		assertEquals(SEL_ONE, workbenchService.getSelection());
+		assertEquals(SEL_ONE, windowService.getSelection());
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertNull(partTwoImpl.input);
+		assertNull(partThreeImpl.input);
+
+		partThreeImpl.setSelection(SEL_TWO);
+		assertEquals(SEL_ONE, workbenchService.getSelection());
+		assertEquals(SEL_ONE, windowService.getSelection());
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertNull(partTwoImpl.input);
+		assertEquals(SEL_TWO, partThreeImpl.input);
+
+		window.set(IContextConstants.ACTIVE_CHILD, partTwo);
+		assertNull(workbenchService.getSelection());
+		assertNull(windowService.getSelection());
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertNull(partTwoImpl.input);
+		assertEquals(SEL_TWO, partThreeImpl.input);
+
+		window.set(IContextConstants.ACTIVE_CHILD, partThree);
+		assertEquals(SEL_TWO, workbenchService.getSelection());
+		assertEquals(SEL_TWO, windowService.getSelection());
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertNull(partTwoImpl.input);
+		assertEquals(SEL_TWO, partThreeImpl.input);
+	}
+
+	public void testPartOneTracksPartThree() throws Exception {
+		IEclipseContext window = TestUtil.createContext(workbenchContext,
+				"windowContext");
+		workbenchContext.set(IContextConstants.ACTIVE_CHILD, window);
+
+		IEclipseContext partOne = TestUtil.createContext(window, "partOne");
+		window.set(IContextConstants.ACTIVE_CHILD, partOne);
+		final TrackingProviderPart partOneImpl = new TrackingProviderPart();
+		ContextInjectionFactory.inject(partOneImpl, partOne);
+
+		IEclipseContext partTwo = TestUtil.createContext(window, "partTwo");
+		ConsumerPart partTwoImpl = new ConsumerPart();
+		ContextInjectionFactory.inject(partTwoImpl, partTwo);
+
+		final IEclipseContext partThree = TestUtil.createContext(window,
+				"partThree");
+		ProviderPart partThreeImpl = new ProviderPart();
+		ContextInjectionFactory.inject(partThreeImpl, partThree);
+
+		partOneImpl.setSelection(SEL_ONE);
+		partThreeImpl.setSelection(SEL_TWO);
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertNull(partOneImpl.otherSelection);
+		assertNull(partTwoImpl.input);
+		assertEquals(SEL_TWO, partThreeImpl.input);
+
+		// part one tracks down part three. this could just as easily be
+		// fronted by the mediator.addSelectionListener(*)
+		partThree.runAndTrack(new Runnable() {
+			public void run() {
+				ESelectionService s = (ESelectionService) partThree
+						.get(ESelectionService.class.getName());
+				partOneImpl.setOtherSelection((String) s.getSelection());
+			}
+		});
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertEquals(SEL_TWO, partOneImpl.otherSelection);
+		assertNull(partTwoImpl.input);
+		assertEquals(SEL_TWO, partThreeImpl.input);
+		
+		partThreeImpl.setSelection(SEL_ONE);
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertEquals(SEL_ONE, partOneImpl.otherSelection);
+		assertNull(partTwoImpl.input);
+		assertEquals(SEL_ONE, partThreeImpl.input);
+		
+		partThreeImpl.setSelection(null);
+		assertEquals(SEL_ONE, partOneImpl.input);
+		assertNull(partOneImpl.otherSelection);
+		assertNull(partTwoImpl.input);
+		assertNull(partThreeImpl.input);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		workbenchContext = createWorkbenchContext(Activator.getDefault()
+				.getGlobalContext());
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		if (workbenchContext instanceof IDisposable) {
+			((IDisposable) workbenchContext).dispose();
+		}
+		workbenchContext = null;
+	}
+
+	private IEclipseContext createWorkbenchContext(IEclipseContext globalContext) {
+		IEclipseContext wb = TestUtil.createContext(globalContext,
+				"workbenchContext");
+		return wb;
+	}
+}
diff --git a/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/TestUtil.java b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/TestUtil.java
new file mode 100644
index 0000000..ccb3935
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/TestUtil.java
@@ -0,0 +1,13 @@
+package org.eclipse.e4.ui.selection.tests;
+
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+
+public class TestUtil {
+	public static IEclipseContext createContext(IEclipseContext parent, String name) {
+		IEclipseContext wb = EclipseContextFactory.create(parent, null);
+		wb.set(IContextConstants.DEBUG_STRING, name);
+		return wb;
+	}
+}