* Performance monitoring view
diff --git a/core/plugins/org.eclipse.dltk.core.tools.ui/.classpath b/core/plugins/org.eclipse.dltk.core.tools.ui/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.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/core/plugins/org.eclipse.dltk.core.tools.ui/.project b/core/plugins/org.eclipse.dltk.core.tools.ui/.project
new file mode 100644
index 0000000..f874a73
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.dltk.core.tools.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/core/plugins/org.eclipse.dltk.core.tools.ui/.settings/org.eclipse.jdt.core.prefs b/core/plugins/org.eclipse.dltk.core.tools.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..4dae18a
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri May 22 14:27:33 NOVST 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/core/plugins/org.eclipse.dltk.core.tools.ui/META-INF/MANIFEST.MF b/core/plugins/org.eclipse.dltk.core.tools.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a69cccc
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.dltk.core.tools.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.dltk.core.tools.ui.DLTKToolsUI
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.dltk.core,
+ org.eclipse.dltk.ui
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
diff --git a/core/plugins/org.eclipse.dltk.core.tools.ui/build.properties b/core/plugins/org.eclipse.dltk.core.tools.ui/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.ui/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/core/plugins/org.eclipse.dltk.core.tools.ui/plugin.xml b/core/plugins/org.eclipse.dltk.core.tools.ui/plugin.xml
new file mode 100644
index 0000000..baed2e2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.ui/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            category="org.eclipse.dltk.ui.main"
+            class="org.eclipse.dltk.core.tools.internal.ui.DLTKPerformanceViewPart"
+            id="org.eclipse.dltk.core.tools.ui.performance.view"
+            name="DLTK Runtime performance"
+            restorable="true">
+      </view>
+   </extension>
+
+</plugin>
diff --git a/core/plugins/org.eclipse.dltk.core.tools.ui/src/org/eclipse/dltk/core/tools/internal/ui/DLTKPerformanceViewPart.java b/core/plugins/org.eclipse.dltk.core.tools.ui/src/org/eclipse/dltk/core/tools/internal/ui/DLTKPerformanceViewPart.java
new file mode 100644
index 0000000..23b5b6b
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.ui/src/org/eclipse/dltk/core/tools/internal/ui/DLTKPerformanceViewPart.java
@@ -0,0 +1,227 @@
+package org.eclipse.dltk.core.tools.internal.ui;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.dltk.core.RuntimePerformanceMonitor;
+import org.eclipse.dltk.core.RuntimePerformanceMonitor.DataEntry;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.TreeColumn;
+import org.eclipse.ui.part.ViewPart;
+
+public class DLTKPerformanceViewPart extends ViewPart {
+
+	private static final int UPDATE_INTERVAL = 500;
+
+	public class PerformanceLabelProvide extends LabelProvider implements
+			ITableLabelProvider {
+
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+			switch (columnIndex) {
+			case 0:
+				if (element instanceof Map.Entry) {
+					return (String) ((Map.Entry) element).getKey();
+				}
+				break;
+			case 1:
+				if (element instanceof Map.Entry) {
+					Map.Entry entry = (Entry) element;
+					if (entry.getValue() instanceof DataEntry) {
+						DataEntry e = (DataEntry) entry.getValue();
+						return Long.toString(e.getTime());
+					}
+				}
+				break;
+			case 2:
+				if (element instanceof Map.Entry) {
+					Map.Entry entry = (Entry) element;
+					if (entry.getValue() instanceof DataEntry) {
+						DataEntry e = (DataEntry) entry.getValue();
+						return Long.toString(e.getTotal());
+					}
+				}
+				break;
+			case 3:
+				if (element instanceof Map.Entry) {
+					Map.Entry entry = (Entry) element;
+					if (entry.getValue() instanceof DataEntry) {
+						DataEntry e = (DataEntry) entry.getValue();
+						return Long.toString(e.getCount());
+					}
+				}
+				break;
+			case 4:
+				if (element instanceof Map.Entry) {
+					Map.Entry entry = (Entry) element;
+					if (entry.getValue() instanceof DataEntry) {
+						DataEntry e = (DataEntry) entry.getValue();
+						if (e.getCount() != 0) {
+							return Double.toString(e.getTime() / e.getCount());
+						}
+					}
+				}
+				break;
+			case 5:
+				if (element instanceof Map.Entry) {
+					Map.Entry entry = (Entry) element;
+					if (entry.getValue() instanceof DataEntry) {
+						DataEntry e = (DataEntry) entry.getValue();
+						if (e.getCount() != 0) {
+							return Double.toString(e.getTotal() / e.getCount());
+						}
+					}
+				}
+				break;
+			case 6:
+				if (element instanceof Map.Entry) {
+					Map.Entry entry = (Entry) element;
+					if (entry.getValue() instanceof DataEntry) {
+						DataEntry e = (DataEntry) entry.getValue();
+						if (e.getTime() != 0) {
+							return Double.toString(e.getTotal() / e.getTime());
+						}
+					}
+				}
+				break;
+			}
+			return "";
+		}
+	}
+
+	private static final class PerformanceContentProvider implements
+			ITreeContentProvider {
+		private static final Object[] NONE_OBJECTS = new Object[0];
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+
+		public void dispose() {
+		}
+
+		public Object[] getElements(Object inputElement) {
+			Map<String, Map<String, DataEntry>> map = RuntimePerformanceMonitor
+					.getAllEntries();
+			return map.entrySet().toArray();
+		}
+
+		public boolean hasChildren(Object element) {
+			if (element instanceof Map) {
+				return !((Map) element).isEmpty();
+			} else if (element instanceof Map.Entry) {
+				Map.Entry e = (Entry) element;
+				Object value = e.getValue();
+				if (value instanceof Map) {
+					Map mval = (Map) value;
+					return !mval.isEmpty();
+				}
+			}
+			return false;
+		}
+
+		public Object getParent(Object element) {
+			return null;
+		}
+
+		public Object[] getChildren(Object parentElement) {
+			if (parentElement instanceof Map) {
+				return ((Map) parentElement).entrySet().toArray();
+			} else if (parentElement instanceof Map.Entry) {
+				Map.Entry e = (Entry) parentElement;
+				if (e.getValue() instanceof Map) {
+					return ((Map) e.getValue()).entrySet().toArray();
+				}
+			}
+			return NONE_OBJECTS;
+		}
+	}
+
+	private TreeViewer viewer;
+
+	public DLTKPerformanceViewPart() {
+	}
+
+	Runnable update = new Runnable() {
+		public void run() {
+			if (!viewer.getTree().isDisposed()) {
+				viewer.refresh();
+				viewer.getTree().getDisplay()
+						.timerExec(UPDATE_INTERVAL, update);
+				viewer.expandAll();
+			}
+		}
+	};
+
+	@Override
+	public void createPartControl(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		composite.setLayout(new GridLayout());
+		viewer = new TreeViewer(composite);
+		viewer.getTree().setHeaderVisible(true);
+		viewer.getTree().setLayoutData(
+				new GridData(SWT.FILL, SWT.FILL, true, true));
+		TreeColumn col = new TreeColumn(viewer.getTree(), SWT.NONE);
+		col.setText("ID");
+		col.setWidth(250);
+
+		TreeColumn time = new TreeColumn(viewer.getTree(), SWT.NONE);
+		time.setText("Time");
+		time.setWidth(80);
+
+		TreeColumn total = new TreeColumn(viewer.getTree(), SWT.NONE);
+		total.setText("Total");
+		total.setWidth(80);
+
+		TreeColumn count = new TreeColumn(viewer.getTree(), SWT.NONE);
+		count.setText("Count");
+		count.setWidth(80);
+
+		TreeColumn avrTime = new TreeColumn(viewer.getTree(), SWT.NONE);
+		avrTime.setText("Avr.Time");
+		avrTime.setWidth(80);
+
+		TreeColumn average = new TreeColumn(viewer.getTree(), SWT.NONE);
+		average.setText("Avr.Count");
+		average.setWidth(80);
+
+		TreeColumn speed = new TreeColumn(viewer.getTree(), SWT.NONE);
+		speed.setText("Speed");
+		speed.setWidth(80);
+
+		viewer.setContentProvider(new PerformanceContentProvider());
+		viewer.setLabelProvider(new PerformanceLabelProvide());
+		viewer.setInput(new Object());
+		parent.getDisplay().timerExec(500, update);
+		Button clear = new Button(composite, SWT.PUSH);
+		clear.setText("Clear");
+		clear.addSelectionListener(new SelectionListener() {
+
+			public void widgetSelected(SelectionEvent e) {
+				RuntimePerformanceMonitor.clear();
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+	}
+
+	@Override
+	public void setFocus() {
+	}
+
+}
diff --git a/core/plugins/org.eclipse.dltk.core.tools.ui/src/org/eclipse/dltk/core/tools/ui/DLTKToolsUI.java b/core/plugins/org.eclipse.dltk.core.tools.ui/src/org/eclipse/dltk/core/tools/ui/DLTKToolsUI.java
new file mode 100644
index 0000000..f91e180
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core.tools.ui/src/org/eclipse/dltk/core/tools/ui/DLTKToolsUI.java
@@ -0,0 +1,50 @@
+package org.eclipse.dltk.core.tools.ui;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class DLTKToolsUI extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.dltk.core.tools.ui";
+
+	// The shared instance
+	private static DLTKToolsUI plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public DLTKToolsUI() {
+	}
+
+	/*
+	 * (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 DLTKToolsUI getDefault() {
+		return plugin;
+	}
+
+}