model elemtn handle identifiers validation
diff --git a/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.classpath b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.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/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.project b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.project
new file mode 100644
index 0000000..2a40823
--- /dev/null
+++ b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.dltk.dev-tools.handle-identifiers</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/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.settings/org.eclipse.jdt.core.prefs b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b50d092
--- /dev/null
+++ b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Apr 21 10:50:16 NOVST 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/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/META-INF/MANIFEST.MF b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..896b86a
--- /dev/null
+++ b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: DLTK Handle Identifiers Tools
+Bundle-SymbolicName: org.eclipse.dltk.dev-tools.handle-identifiers;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.ui,
+ org.eclipse.dltk.core;bundle-version="2.0.0",
+ org.eclipse.dltk.ui;bundle-version="2.0.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/build.properties b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/plugin.xml b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/plugin.xml
new file mode 100644
index 0000000..246102b
--- /dev/null
+++ b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension point="org.eclipse.ui.views">
+         <view
+               class="org.eclipse.dltk.devtools.handleidentitiers.HandleIdentifiersView"
+               id="org.eclipse.dltk.devtools.HandleIdentifiersView"
+               name="Handle Identifiers"
+               restorable="true">
+         </view>
+   </extension>
+</plugin>
diff --git a/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/src/org/eclipse/dltk/devtools/handleidentitiers/HandleIdentifiersView.java b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/src/org/eclipse/dltk/devtools/handleidentitiers/HandleIdentifiersView.java
new file mode 100644
index 0000000..1436089
--- /dev/null
+++ b/core/tools/org.eclipse.dltk.dev-tools.handle-identifiers/src/org/eclipse/dltk/devtools/handleidentitiers/HandleIdentifiersView.java
@@ -0,0 +1,205 @@
+package org.eclipse.dltk.devtools.handleidentitiers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IModelElementVisitor;
+import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.ui.viewsupport.ScriptUILabelProvider;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+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.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.part.ViewPart;
+
+public class HandleIdentifiersView extends ViewPart {
+
+	Composite content;
+	Combo projectNames;
+	TableViewer output;
+
+	private static class HandleIdentifierContentProvider implements
+			IStructuredContentProvider {
+
+		public void dispose() {
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+
+		public Object[] getElements(Object inputElement) {
+			if (inputElement instanceof List<?>) {
+				return ((List<?>) inputElement).toArray();
+			} else {
+				return new Object[0];
+			}
+		}
+
+	}
+
+	private static class HandleIdentifierLabelProvider extends LabelProvider
+			implements ITableLabelProvider {
+
+		private final ScriptUILabelProvider scriptProvider = new ScriptUILabelProvider();
+
+		@Override
+		public String getText(Object element) {
+			return getColumnText(element, 0);
+		}
+
+		public Image getColumnImage(Object element, int columnIndex) {
+			if (element instanceof Record) {
+				final Record record = (Record) element;
+				switch (columnIndex) {
+				case 0:
+					return scriptProvider.getImage(record.element);
+				}
+			}
+			return super.getImage(element);
+		}
+
+		public String getColumnText(Object element, int columnIndex) {
+			if (element instanceof Record) {
+				final Record record = (Record) element;
+				switch (columnIndex) {
+				case 0:
+					return scriptProvider.getText(record.element);
+				case 1:
+					return record.identifier;
+				case 2:
+					return record.status.toString();
+				}
+			}
+			return super.getText(element);
+		}
+
+	}
+
+	private enum Status {
+		OK, EXCEPTION, ERROR, NULL
+	}
+
+	private static class Record {
+
+		public Record(IModelElement element, String identifier, Status status) {
+			this.element = element;
+			this.identifier = identifier;
+			this.status = status;
+		}
+
+		final IModelElement element;
+		final String identifier;
+		final Status status;
+	}
+
+	@Override
+	public void createPartControl(Composite parent) {
+		content = new Composite(parent, SWT.NONE);
+		content.setLayoutData(new GridData(GridData.FILL_BOTH));
+		content.setLayout(new GridLayout());
+		final Composite top = new Composite(content, SWT.NONE);
+		top.setLayout(new GridLayout(3, false));
+		top.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		new Label(top, SWT.NONE).setText("Project");
+		projectNames = new Combo(top, SWT.BORDER | SWT.READ_ONLY);
+		output = new TableViewer(content);
+		output.getTable().setHeaderVisible(true);
+		final TableColumn nameColumn = new TableColumn(output.getTable(),
+				SWT.LEFT);
+		nameColumn.setText("Name");
+		nameColumn.setWidth(200);
+		final TableColumn idColumn = new TableColumn(output.getTable(),
+				SWT.LEFT);
+		idColumn.setText("Identifier");
+		idColumn.setWidth(500);
+		final TableColumn statusColumn = new TableColumn(output.getTable(),
+				SWT.LEFT);
+		statusColumn.setText("Status");
+		statusColumn.setWidth(100);
+		output.setContentProvider(new HandleIdentifierContentProvider());
+		output.setLabelProvider(new HandleIdentifierLabelProvider());
+		output.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
+		final List<String> names = new ArrayList<String>();
+		try {
+			for (IScriptProject project : DLTKCore.create(getWorkspaceRoot())
+					.getScriptProjects()) {
+				names.add(project.getElementName());
+			}
+		} catch (ModelException e) {
+			e.printStackTrace();
+		}
+		projectNames.setItems(names.toArray(new String[names.size()]));
+		Button btnDo = new Button(top, SWT.PUSH);
+		btnDo.setText("Validate");
+		btnDo.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				SafeRunnable r = new SafeRunnable() {
+					public void run() throws Exception {
+						IScriptProject project = DLTKCore
+								.create(getWorkspaceRoot().getProject(
+										projectNames.getText()));
+						validateHandleIdentifiers(project);
+					}
+				};
+				SafeRunner.run(r);
+			}
+		});
+	}
+
+	private void validateHandleIdentifiers(IScriptProject project)
+			throws ModelException {
+		final List<Record> records = new ArrayList<Record>();
+		project.accept(new IModelElementVisitor() {
+
+			public boolean visit(IModelElement element) {
+				final String identifier = element.getHandleIdentifier();
+				Status status;
+				try {
+					final IModelElement x = DLTKCore.create(identifier);
+					if (x == null) {
+						status = Status.NULL;
+					} else if (x.equals(element)) {
+						status = Status.OK;
+					} else {
+						status = Status.ERROR;
+					}
+				} catch (Exception e) {
+					status = Status.EXCEPTION;
+				}
+				records.add(new Record(element, identifier, status));
+				return true;
+			}
+		});
+		output.setInput(records);
+	}
+
+	@Override
+	public void setFocus() {
+		output.getTable().setFocus();
+	}
+
+	protected static IWorkspaceRoot getWorkspaceRoot() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+}