/*******************************************************************************
 * 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.bpel.ui.util;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.xml.namespace.QName;

import org.eclipse.bpel.common.extension.model.ExtensionMap;
import org.eclipse.bpel.common.ui.ImageUtils;
import org.eclipse.bpel.common.ui.details.viewers.ComboViewer;
import org.eclipse.bpel.common.ui.details.widgets.DecoratedLabel;
import org.eclipse.bpel.common.ui.markers.ModelMarkerUtil;
import org.eclipse.bpel.model.BPELFactory;
import org.eclipse.bpel.model.BPELPackage;
import org.eclipse.bpel.model.Catch;
import org.eclipse.bpel.model.CompensateScope;
import org.eclipse.bpel.model.CorrelationSet;
import org.eclipse.bpel.model.CorrelationSets;
import org.eclipse.bpel.model.Flow;
import org.eclipse.bpel.model.ForEach;
import org.eclipse.bpel.model.Invoke;
import org.eclipse.bpel.model.OnEvent;
import org.eclipse.bpel.model.PartnerLink;
import org.eclipse.bpel.model.PartnerLinks;
import org.eclipse.bpel.model.Process;
import org.eclipse.bpel.model.Scope;
import org.eclipse.bpel.model.Sequence;
import org.eclipse.bpel.model.Variable;
import org.eclipse.bpel.model.Variables;
import org.eclipse.bpel.model.adapters.AdapterRegistry;
import org.eclipse.bpel.model.messageproperties.MessagepropertiesPackage;
import org.eclipse.bpel.model.messageproperties.PropertyAlias;
import org.eclipse.bpel.model.partnerlinktype.PartnerlinktypePackage;
import org.eclipse.bpel.model.util.BPELUtils;
import org.eclipse.bpel.names.NCNameWordDetector;
import org.eclipse.bpel.runtimes.IBPELModuleFacetConstants;
import org.eclipse.bpel.ui.BPELEditor;
import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.IBPELUIConstants;
import org.eclipse.bpel.ui.Messages;
import org.eclipse.bpel.ui.Policy;
import org.eclipse.bpel.ui.adapters.BPELUIAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIExtensionAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIMessagePropertiesAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIPartnerLinkTypeAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIWSDLAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIWSILAdapterFactory;
import org.eclipse.bpel.ui.adapters.BPELUIXSDAdapterFactory;
import org.eclipse.bpel.ui.adapters.IContainer;
import org.eclipse.bpel.ui.adapters.ILabeledElement;
import org.eclipse.bpel.ui.adapters.INamedElement;
import org.eclipse.bpel.ui.bpelactions.AbstractBPELAction;
import org.eclipse.bpel.ui.dialogs.NamespaceMappingDialog;
import org.eclipse.bpel.ui.editparts.BPELEditPart;
import org.eclipse.bpel.ui.editparts.FlowEditPart;
import org.eclipse.bpel.ui.editparts.InvokeEditPart;
import org.eclipse.bpel.ui.editparts.LinkEditPart;
import org.eclipse.bpel.ui.editparts.ScopeEditPart;
import org.eclipse.bpel.ui.editparts.StartNodeEditPart;
import org.eclipse.bpel.ui.editparts.borders.GradientBorder;
import org.eclipse.bpel.ui.editparts.util.OverlayCompositeImageDescriptor;
import org.eclipse.bpel.ui.extensions.ActionDescriptor;
import org.eclipse.bpel.ui.extensions.BPELUIRegistry;
import org.eclipse.bpel.ui.uiextensionmodel.ActivityExtension;
import org.eclipse.bpel.ui.uiextensionmodel.UiextensionmodelPackage;
import org.eclipse.bpel.validator.EmfModelQuery;
import org.eclipse.bpel.wsil.model.inspection.InspectionPackage;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.gef.AccessibleEditPart;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.Tool;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.WSDLPackage;
import org.eclipse.wst.wsdl.util.WSDLResourceImpl;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDPackage;


/**
 * BPELUtil is a place to put *static* helper methods for the BPEL editor.
 *
 * Note that helpers which have specifically to do with accessing model objects are
 * usually found in the ModelHelper class.
 */
public class BPELUtil {

	private static final Variable[] EMPTY_VARIABLE_ARRAY = new Variable[0];
	private static final PartnerLink[] EMPTY_PARTNERLINK_ARRAY = new PartnerLink[0];
	private static final CorrelationSet[] EMPTY_CORRELATIONSET_ARRAY = new CorrelationSet[0];

	/**
	 * This global variable stores the path of the last WSDL file selected with
	 * a WorkbenchFileSelectionDialog.
	 */
	public static IPath lastWSDLFilePath = null;
	/**
	 * Global variable storing the path of the last BPEL file selected
	 */
	public static IPath lastBPELFilePath = null;

	/**
	 * Global variable storing the path of the last XSD file selected
	 */
	public static IPath lastXSDFilePath;


	static {
		AdapterRegistry.INSTANCE.registerAdapterFactory(
				BPELPackage.eINSTANCE, BPELUIAdapterFactory.getInstance());

		AdapterRegistry.INSTANCE.registerAdapterFactory(
			    WSDLPackage.eINSTANCE, BPELUIWSDLAdapterFactory.getInstance());

		AdapterRegistry.INSTANCE.registerAdapterFactory(
			    PartnerlinktypePackage.eINSTANCE, BPELUIPartnerLinkTypeAdapterFactory.getInstance());

		AdapterRegistry.INSTANCE.registerAdapterFactory(
			    XSDPackage.eINSTANCE, BPELUIXSDAdapterFactory.getInstance());

		AdapterRegistry.INSTANCE.registerAdapterFactory(
			    MessagepropertiesPackage.eINSTANCE, BPELUIMessagePropertiesAdapterFactory.getInstance());

		AdapterRegistry.INSTANCE.registerAdapterFactory(
			    UiextensionmodelPackage.eINSTANCE, BPELUIExtensionAdapterFactory.getInstance());

		AdapterRegistry.INSTANCE.registerAdapterFactory(
			    InspectionPackage.eINSTANCE, BPELUIWSILAdapterFactory.getInstance() );

	}


	/**
	 * Register adapter factory for the given EClass.
	 *
	 * @param key
	 * @param factory
	 */

	public static void registerAdapterFactory(EClass key, AdapterFactory factory) {
		AdapterRegistry.INSTANCE.registerAdapterFactory(key,factory);
	}

	public static void registerAdapterFactory(EPackage key, AdapterFactory factory) {
		AdapterRegistry.INSTANCE.registerAdapterFactory(key, factory);
	}

	static Class<?> adapterInterface ( Object type ) {

		if (type instanceof Class) {
			return (Class) type;
		}

		if (type instanceof String) {
			try {
				return Class.forName((String)type);
			} catch (ClassNotFoundException e) {
				throw new RuntimeException(e);
			}
		}

		throw new RuntimeException("Adapter type " + type + " is not understood.");		 //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * @param <T>
	 * @param target
	 * @param clazz
	 * @return the adapted interface or object
	 */
	public static <T extends Object> T adapt ( Object target,  Class<T> clazz) {
		return AdapterRegistry.INSTANCE.adapt(target, clazz);
	}



	/**
	 * This method tries the registered adapter factories one by one, returning
	 * the first non-null result it gets.  If none of the factories can adapt
	 * the result, it returns null.
	 * @param target target object
	 * @param type type of the adapter to find
	 * @return the adapter for the target.
	 */

	public static Object adapt (Object target, Object type) {
		return AdapterRegistry.INSTANCE.adapt(target, type);
	}


	/**
	 * Create an adapter for the given target of the given type.
	 * In addition, pass a context object to the adapter(s) of the target.
	 *
	 * The idea is that some adapters can be stateful and depend not only
	 * on the objects that they wrap, but also on some other context that is needed
	 * to completely and correctly implement the interface for which the adaptor is
	 * needed.
	 *
	 * Adapters that are stateless, should ignore any notifications sent to them.
	 *
	 * @param target the target object
	 * @param type the type it wants to adapt to
	 * @param context the context object
	 *
	 * @return the adapter
	 */
	public static Object adapt (Object target, Object type, Object context) {
		return AdapterRegistry.INSTANCE.adapt(target, type,context);
	}


	/**
	 * Returns the effective EClass for a custom activity (action).
	 */
	public static EClass getEClassFor(Object target) {
	    if (target instanceof Invoke) {
	        ActionDescriptor[] descriptors = BPELUIRegistry.getInstance().getActionDescriptors();
	        for( ActionDescriptor descriptor : descriptors ) {
	            AbstractBPELAction action = descriptor.getAction();
                if (action.isInstanceOf(target)) {
                    return action.getModelType();
                }
            }
	    }
	    if (!(target instanceof EObject)) {
	        return null;
	    }
	    return ((EObject)target).eClass();
	}

	public static boolean isCustomActivity(Object target) {
        if (target instanceof Invoke) {
	        ActionDescriptor[] descriptors = BPELUIRegistry.getInstance().getActionDescriptors();
	        for( ActionDescriptor descriptor : descriptors ) {
	            AbstractBPELAction action = descriptor.getAction();
	            if (action.getModelType() == BPELPackage.eINSTANCE.getInvoke()) continue;
                if (action.isInstanceOf(target)) {
                    return true;
                }
            }
        }
		return false;
	}

	public static boolean isBPELAction(EClass target) {
		ActionDescriptor[] descriptors = BPELUIRegistry.getInstance().getActionDescriptors();
        for( ActionDescriptor descriptor : descriptors ) {
            AbstractBPELAction action = descriptor.getAction();
            if (action.getModelType() == target) {
                return true;
            }
        }
		return false;
	}

	/**
	 * Creates a new instance of clazz using the EFactory of the EPackage clazz belongs to.
	 */
	public static EObject createEObject(EClass clazz) {
		return clazz.getEPackage().getEFactoryInstance().create(clazz);
	}

	// This is a hack to bundle the result of a cloneSubtree with enough state to undo/redo
	// the extension map changes it caused.
	public static class CloneResult {

		/** The result of the clone */
		public EObject targetRoot;
		Map<EObject,EObject> targetMap;
		Map<EObject,EObject> targetMapAdditions = new HashMap<EObject,EObject>();

		/**
		 * Undo ... ?
		 */
		public void undo() {
			for (EObject next : this.targetMapAdditions.keySet()) {
				this.targetMap.remove(next);
			}
		}

		/**
		 * Redo ... ?
		 */
		public void redo() {
			for (EObject key : this.targetMapAdditions.keySet()) {
				this.targetMap.put(key, this.targetMapAdditions.get(key));
			}
		}
	}

	// This helper is used by the cloneSubtree() method.
	protected static void cloneSubtreeHelper (EObject source, Map<EObject,EObject> sourceMap, Map<EObject,EObject> targetMap,
		Map<EObject,EObject> copyMap, CloneResult result)
	{
		EObject targetObject = createEObject(source.eClass());
		copyMap.put(source, targetObject);

		if (sourceMap != null && sourceMap.containsKey(source)) {

			EObject sourceExtension = sourceMap.get(source);
			EObject targetExtension = createEObject(sourceExtension.eClass());

			copyMap.put(sourceExtension, targetExtension);

			for (TreeIterator<?> it2 = sourceExtension.eAllContents(); it2.hasNext(); ) {
				EObject source2 = (EObject)it2.next();
				EObject target2 = createEObject(source2.eClass());
				copyMap.put(source2, target2);
			}

			targetMap.put(targetObject, targetExtension);
			result.targetMapAdditions.put(targetObject, targetExtension);
		}
	}

	/**
	 * Clones an EObject and all EObjects contained directly or indirectly within it.  All
	 * cloned objects possessing an extension in the sourceMap will also have their extensions
	 * cloned into the targetMap.  Containment references and other references to any of the
	 * cloned object(s) will be fixed up to point into the target objects.  Any references to
	 * non-cloned objects will be copied as-is in the cloned objects.
	 *
	 * NOTE: This method relies on BPELUtil.createEObject() knowing how to create new instances
	 * of the EClasses of all copied objects (i.e. objectFactories must contain the necessary
	 * EFactory instances for everything copied by this method).
	 *
	 * @param source The root of the source subtree to clone.
	 * @param sourceMap The extension map containing source extensions of cloned objects.
	 * @param targetMap The extension map in which cloned extensions should be recorded.
	 * @return a CloneResult containing the root of the target subtree, which can be used
	 * for undo/redo.
	 */
	@SuppressWarnings("nls")
	public static CloneResult cloneSubtree (EObject source, Map<EObject,EObject> sourceMap, Map<EObject,EObject> targetMap) {

		HashMap<EObject,EObject> copyMap = new HashMap<EObject,EObject>();

		CloneResult result = new CloneResult();
		result.targetMap = targetMap;

		// (1) Create target objects for each EObject in the containment subtree of source.
		// If the source object has an extension in sourceMap, create copies of the extension
		// and its containment tree as well.
		// NOTE: we can NOT just recursively call cloneSubtree for the extension, it wouldn't
		// work with fixing up references.  We have to iterate its eAllContents also here.

		cloneSubtreeHelper(source, sourceMap, targetMap, copyMap, result);

		for (TreeIterator<?> it = source.eAllContents(); it.hasNext(); ) {
			EObject sourceObject = (EObject)it.next();
			cloneSubtreeHelper(sourceObject, sourceMap, targetMap, copyMap, result);
		}

		// (2) Copy the features from each cloned source object to the corresponding target
		// object.  As we copy, we replace any references to cloned source objects with
		// references to the corresponding target objects--but references to non-cloned
		// objects are copied as-is.

		for (Map.Entry<EObject,EObject> entry : copyMap.entrySet() ) {

			EObject sourceObject = entry.getKey();
			EObject targetObject = entry.getValue();

			if (sourceObject.eClass() != targetObject.eClass()) {
				throw new IllegalStateException("Source and target objects are not of the same class after cloning.");
			}

			if (Policy.DEBUG) {
				System.out.println("copying a "+sourceObject.eClass().getName()); //$NON-NLS-1$
			}

			for ( EStructuralFeature feature : sourceObject.eClass().getEAllStructuralFeatures()) {

				// special cases first.
				if (!feature.isChangeable()) {
					if (Policy.DEBUG) System.out.println("  *** skipping unchangeable feature "+feature); //$NON-NLS-1$
					continue;
				}

				if (feature.isUnsettable() && !targetObject.eIsSet(feature)) {
					if (Policy.DEBUG) System.out.println("  unsetting feature "+feature.getName()); //$NON-NLS-1$
					targetObject.eUnset(feature);
					continue;
				}

				Object value = sourceObject.eGet(feature);

				boolean treatAsReference = (feature instanceof EReference);

				if (treatAsReference) {
					if (feature.isMany()) {
						// list of references.
						EList<Object> newValues = new BasicEList<Object>();
						if (Policy.DEBUG) System.out.println("  copying multi-reference feature "+feature.getName()+":"); //$NON-NLS-1$ //$NON-NLS-2$

						for (Iterator<?> it3 = ((Collection)value).iterator(); it3.hasNext(); ) {
							Object oldValue = it3.next();
							Object newValue = (oldValue==null ? null : copyMap.get(oldValue));

							if (newValue == null)  {
								newValue = oldValue;
							}
							if (Policy.DEBUG) System.out.println("+ (oldValue="+oldValue+" newValue="+newValue+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
							newValues.add(newValue);
						}
						targetObject.eSet(feature, newValues);
					} else {
						// single reference.
						Object newValue = (value==null? null : copyMap.get(value));
						if (newValue == null)  {
							newValue = value;
						}
						if (Policy.DEBUG) System.out.println("  copying reference feature "+feature.getName() //$NON-NLS-1$
							+" (value="+value+" newValue="+newValue+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						targetObject.eSet(feature, newValue);
					}
				} else {

					/** In case of a DOM Node and the "element" feature, we simply clone the result */
					if (value instanceof org.w3c.dom.Node && "element".equals(feature.getName())) {
						org.w3c.dom.Node  e = (org.w3c.dom.Node)value;
						value = e.cloneNode(true);
					}

					// non-reference attribute.  just copy the value
					if (Policy.DEBUG) System.out.println("  copying attr feature "+feature.getName()+" (value="+value+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					targetObject.eSet(feature, value);
				}
			}
		}

		result.targetRoot = copyMap.get(source);
		return result;
	}


	/**
	 * Convenience formatting methods.
	 */
	public static String formatString(String format, String arg1) {
		return MessageFormat.format(format, new Object[] { arg1 });
	}
	public static String formatString(String format, String arg1, String arg2) {
		return MessageFormat.format(format, new Object[] { arg1, arg2 });
	}

	/**
	 * strips out invalid characters to conform to QName specs.
	 * If the resulting name is null, returns "bpel" as a valid QName
	 * to guarantee that something valid is returned.
	 *
	 * TODO: This has to be a valid NCName ...
	 *
	 * @param str
	 *
	 * @return
	 */

	public static String generateValidName(String str) {

		StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
		if (str != null) {
			for(char ch : str.trim().toCharArray()) {
				int destLength = result.length();
				if (((destLength == 0) && (Character.isLetter(ch) || ch == '_'))
					|| ((destLength > 0) && Character.isJavaIdentifierPart(ch))) {
					result.append(ch);
				}
			}
		}

		if (result.length() == 0)
			result.append(IBPELUIConstants.EXTENSION_BPEL);

		return result.toString();
	}

	/**
	 * Helper that traverses the IContainer hierarchy of the given modelObject in depth
	 * first fashion and applies the given visitor to each node.
	 *
	 * DO NOT USE THIS for anything that must see "all" model objects (including implicit
	 * sequences, for example).  Use TreeIterator modelObject.eAllContents() for that.
	 */
	public static void visitModelDepthFirst(Object modelObject, IModelVisitor visitor) {
		if (visitor.visit(modelObject)) {
			IContainer container = BPELUtil.adapt(modelObject, IContainer.class);
			if (container != null) {
				for (Iterator it = container.getChildren(modelObject).iterator(); it.hasNext(); ) {
					visitModelDepthFirst(it.next(), visitor);
				}
			}
			// TODO: Make this go away
			if (modelObject instanceof Flow) {
				// Hack: also visit the links of a flow!
				Flow flow = (Flow)modelObject;
				for (Iterator it = FlowLinkUtil.getFlowLinks(flow).iterator(); it.hasNext(); ) {
					visitModelDepthFirst(it.next(), visitor);
				}
			}
		}
	}

	private static class NameUnusedVisitor implements IModelVisitor {
		private boolean unused = true;
		private final String candidateName;
		private final Collection<EObject> ignoreObjects;

		NameUnusedVisitor(String candidateName, Collection<EObject> ignoreObjects) {
			this.candidateName = candidateName;
			if (ignoreObjects == null)  ignoreObjects = Collections.emptySet();
			this.ignoreObjects = ignoreObjects;
		}

		@Override
		public boolean visit(Object child) {
			if (!this.ignoreObjects.contains(child)) {
			INamedElement namedElement = BPELUtil.adapt(child, INamedElement.class);
				if (namedElement != null) {
					String name = namedElement.getName(child);
					if ((name != null) && (name.compareToIgnoreCase(this.candidateName) == 0))
						this.unused = false;
				}
			}
			return true;//unused;
		}

		public boolean isUnused() {
			return this.unused;
		}
	}

	/**
	 * checks if a name is available for use within the given process (i.e. if this name
	 * were added within the modelRoot, would it be unique).
	 */
	public static boolean isNameUnused(EObject modelRoot, String candidateName, Collection ignoreObjects) {
		NameUnusedVisitor visitor = new NameUnusedVisitor(candidateName, ignoreObjects);
		for (TreeIterator<EObject> it = modelRoot.eAllContents(); it.hasNext(); ) {
			visitor.visit(it.next());
			if (visitor.isUnused() == false) return false;
		}
		return true;
	}

	/**
	 * return a mangled name (based on the given hint) which is unique in the given process.
	 */
	public static String getUniqueModelName(EObject context, String hint, Collection ignoreObjects) {
		return getUniqueModelName2(context, hint, ignoreObjects);
	}

	/**
	 * return a mangled name (based on the given hint) which is unique in the given WSDL definition.
	 */
	public static String getUniqueModelName (Definition definition, String hint, Collection ignoreObjects) {
		return getUniqueModelName2(definition, hint, ignoreObjects);
	}

	protected static String getUniqueModelName2 (EObject modelRoot, String hint, Collection ignoreObjects) {

		// first try it exactly as hinted.
		String result = BPELUtil.generateValidName((hint==null)?"":hint.trim()); //$NON-NLS-1$
		if (isNameUnused(modelRoot, result, ignoreObjects))  return result;

		// go back to the first non-digit
		int digitPos = result.length()-1;
		while (digitPos >= 0 && Character.isDigit(result.charAt(digitPos)))  digitPos--;
		digitPos++; // move back to the digit
		String nameWithoutNum = result.substring(0, digitPos);

		// try increasing numbers until one is accepted.
		for (int num = 1; ; num++)  {
			result = nameWithoutNum+String.valueOf(num);
			if (isNameUnused(modelRoot, result, ignoreObjects))  return result;
		}
	}

	public static String generateUniqueModelName (EObject context, String hint, EObject model) {

		if (hint == null || "".equals(hint)) { //$NON-NLS-1$
			ILabeledElement element = BPELUtil.adapt(model, ILabeledElement.class);
			hint = (element != null) ? element.getTypeLabel(model) : ""; //$NON-NLS-1$
		}
		return BPELUtil.getUniqueModelName(context, hint, Collections.singletonList(model));
	}

	public static String getFilenameFromUri(String uri) {
		if (uri == null)  return Messages.BPELUtil__unknown_URI__54;
		// Hack. Why aren't we just using URI objects?
		int idx = Math.max(uri.lastIndexOf("/"), uri.lastIndexOf("\\")); //$NON-NLS-1$ //$NON-NLS-2$
		return (idx >= 0)? uri.substring(idx+1) : uri;
	}

	/**
	 * Converts the first letter of the target String to upper case.
	 * @param target
	 * @return the name with the first letter uppercased.
	 */
	public static String upperCaseFirstLetter (String target) {
		if (target.length() < 1) {
			return target;
		}
		StringBuilder buf = new StringBuilder (target.length());
		buf.append(target.substring(0, 1).toUpperCase());
		buf.append(target.substring(1, target.length()));
		return buf.toString();
	}

	/**
	 * Converts the first letter of the target String to lower case.
	 */
	public static String lowerCaseFirstLetter(String target) {
		if (target.length() < 1) {
			return target;
		}
		StringBuffer buf = new StringBuffer(target.length());
		buf.append(target.substring(0, 1).toLowerCase());
		buf.append(target.substring(1, target.length()));
		return buf.toString();
	}

	/**
	 * Returns all of the PropertyAlias objects from WSDL files in the same ResourceSet as
	 * the resource containing messageType, which are aliases for messageType.
	 */
	public static List<PropertyAlias> getPropertyAliasesForMessageType(Message messageType) {
		List<PropertyAlias> aliases = new ArrayList<PropertyAlias>();
		Resource resource = messageType.eResource();
		if (resource == null) {
			return aliases;
		}
		ResourceSet resourceSet = resource.getResourceSet();
		for (Iterator<Resource> it = resourceSet.getResources().iterator(); it.hasNext(); ) {
			resource = it.next();
			// TODO: this is a hack.  Why is there no WSDLResource interface??
			if (resource instanceof WSDLResourceImpl) {
				for (TreeIterator<EObject> treeIt = resource.getAllContents(); treeIt.hasNext(); ) {
					EObject object = treeIt.next();
					if (object instanceof PropertyAlias) {
						PropertyAlias alias = (PropertyAlias)object;
						if (messageType.equals(alias.getMessageType()))
							aliases.add(alias);
					}
				}
			}
		}
		return aliases;
	}

	// Creates an implicit sequence with a name that is unique in the editor's process.
	// Note that an ActivityExtension is created and inserted in the extension map,
	// but the implicit sequence itself should be inserted in the model by the caller.
	public static Sequence createImplicitSequence (Process process, ExtensionMap extensionMap) {
		Sequence impSeq = BPELFactory.eINSTANCE.createSequence();
		ModelHelper.createExtensionIfNecessary(extensionMap, impSeq);
		Collection ignoreObjects = Collections.singletonList(impSeq);
		if (ModelHelper.isSpecCompliant(process)) {
			impSeq.setName(getUniqueModelName(process, Messages.BPELUtil_Sequence_1, ignoreObjects));
		} else {
			impSeq.setName(getUniqueModelName(process, Messages.BPELUtil_HiddenSequence_2, ignoreObjects));
			((ActivityExtension)ModelHelper.getExtension(impSeq)).setImplicit(true);
		}
		// TODO: also give sequence a unique ID marked as implicit!
		return impSeq;
	}

	public static TreeIterator nodeAndAllContents(final EObject node) {
		final TreeIterator<EObject> allContents = node.eAllContents();
		return new TreeIterator() {
			boolean didNode = false;
			@Override
			public void prune() {
				// TODO: This won't work when calling on the first item.
				if (!this.didNode) throw new IllegalStateException();
				allContents.prune();
			}

			@Override
			public boolean hasNext() {
				if (this.didNode) return allContents.hasNext();
				return node != null;
			}

			@Override
			public Object next() {
				if (this.didNode) return allContents.next();
				this.didNode = true;	return node;
			}

			@Override
			public void remove() {
				// This won't work when calling on the first item.
				if (!this.didNode) throw new IllegalStateException();
				allContents.remove();
			}
		};
	}

	private static class RefreshActionVisitor implements IModelVisitor {
		private final GraphicalViewer viewer;
		public RefreshActionVisitor(GraphicalViewer viewer) {
			this.viewer = viewer;
		}

		@Override
		public boolean visit(Object child) {
			EditPart ep = (EditPart) this.viewer.getEditPartRegistry().get(child);
			if (ep != null && ep instanceof BPELEditPart) {
				IFigure fig = ((BPELEditPart)ep).getContentPane();
				if (fig != null) {
					((BPELEditPart)ep).regenerateVisuals();
					ep.refresh();
				}
			}
			if(ep instanceof LinkEditPart){
				ep.refresh();
			}
			return true;//unused;
		}
	}

	/**
	 * refreshes all the editparts of the process. Useful for changing layouts etc
	 */
	public static void regenerateVisuals(Process process, GraphicalViewer viewer) {
		RefreshActionVisitor visitor = new RefreshActionVisitor(viewer);
		visitModelDepthFirst(process, visitor);
		return;
	}


	/**
	 * The policy for whether a BPELEditPart's edges should be hilighted or not.  This one defers
	 * to the active tool if it is an IHilightControllingTool and says no otherwise.
	 */
	public static boolean shouldHilightEdges(EditDomain domain, EObject modelObject) {
		Tool tool = domain.getActiveTool();
		if (tool instanceof IHilightControllingTool) {
			return ((IHilightControllingTool)tool).hilightModelTarget(modelObject);
		}
		return false;
	}


	/**
	 * Used to determine the type of pattern to paint a container in the Process.
	 * Because the nesting of containers is confusing, we want to draw nice gradients
	 * to help the user.
	 * 1 and 3 return values mean solid fill.
	 * 0 and 2 mean gradient fills.
	 */
	public static int getRepaintFillType(IFigure fig) {
		int depth = 0;
		IFigure parent = fig.getParent();
		while (parent != null) {
			if (parent != null && parent.getBorder() != null &&  parent.getBorder() instanceof GradientBorder) {
				depth++;
			}
			parent = parent.getParent();
		}
		return depth % 4;
	}

	public static void sortFlowList(List<FlowEditPart> listOfFlowEditParts) {
		List<FlowEditPart> result = listOfFlowEditParts;
		int resultSize = result.size();

		for (int i = 0; i<resultSize; i++) {
			for (int j = i+1; j<resultSize; j++) {
				Flow flow1 = (Flow)(result.get(i)).getModel();
				Flow flow2 = (Flow)(result.get(j)).getModel();
				Flow[] parents = FlowLinkUtil.getParentFlows(flow2);
				for( Flow parent : parents ) {
					if (parent == flow1) {
						// flow2 must be layed out before flow1 so its size will be known!
						FlowEditPart temp = result.get(i);
						result.set(i, result.get(j));
						result.set(j, temp);
					}
				}
			}
		}
	}

	/**
	 * Refresh the given ComboViewer, and also make sure selectedObject is selected in it.
	 */
	public static void refreshCombo(ComboViewer viewer, Object selectedObject) {
		viewer.refresh();
		String s = ((ILabelProvider)viewer.getLabelProvider()).getText(selectedObject);
		viewer.getCombo().setText(s);
	}

	/**
	 * Helper method to calculate the width of a button.
	 * This is necessary for internationalization and accessibility.
	 * Returned value is the calculated width or defaultSize, whichever
	 * is larger.
	 */
	public static int calculateButtonWidth(Widget widget, int defaultSize){
		GC gc;
		int width = 0;

		if (widget instanceof Button) {
			Button w = (Button)widget;
			gc = new GC(w);
			gc.setFont(w.getFont());
			width = gc.textExtent(w.getText()).x + 17;
			gc.dispose();
			return Math.max(width, defaultSize);
		}
		return defaultSize;
	}


	public static String getMaxLengthString(String strings[]) {
		int max = -1;
		int index = -1;
		for (int i = 0; i < strings.length; i++) {
			if (strings[i].length() > max) {
				max = strings[i].length();
				index = i;
			}
		}

		if (index >= 0) return strings[index];
		return "";  //$NON-NLS-1$
	}

	/**
	 * Helper method to calculate the width of a CLabel.
	 * This is necessary for internationalization and accessibility.
	 *
	 * Returned value is the calculated width or defaultSize, whichever
	 * is larger.
	 */
	public static int calculateLabelWidth(Widget widget, int defaultSize){
		GC gc;
		int width = 0;

		if (widget instanceof CLabel) {
			CLabel w = (CLabel)widget;
			gc = new GC(w);
			gc.setFont(w.getFont());
			width = gc.textExtent(w.getText()).x + 17;
			gc.dispose();

			return Math.max(width, defaultSize);
		}
		if (widget instanceof DecoratedLabel) {
			DecoratedLabel w = (DecoratedLabel)widget;
			gc = new GC(w);
			gc.setFont(w.getFont());
			width = gc.textExtent(w.getText()).x + 17;
			gc.dispose();
			return Math.max(width, defaultSize);
		}


		if (widget instanceof Label) {
			Label w = (Label)widget;
			gc = new GC(w);
			gc.setFont(w.getFont());
			width = gc.textExtent(w.getText()).x + 5;
			gc.dispose();
			return Math.max(width, defaultSize);
		}
		return defaultSize;
	}

	public static IFile getFileFromURI(URI uri) {
		if (uri.isFile()) {
			return getFileFromDeviceURI(uri);
		}
		return getFileFromPlatformURI(uri);
	}

	public static IFile getFileFromDeviceURI(URI uri) {
		String device = uri.device();
		Iterator pathIt = uri.segmentsList().iterator();
		StringBuffer path = new StringBuffer();
		while (pathIt.hasNext()) {
			path.append("/" + pathIt.next()); //$NON-NLS-1$
		}
		return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(device, path.toString()));
	}

	public static IFile getFileFromPlatformURI(URI uri) {
		String [] segs  = uri.segments();
		IPath path = null;
		// start at 1 to skip resource
		for (int i = 1; i< segs.length; i++) {
			if (path == null) {
				path = new Path(segs[i]);
			} else {
				path = path.append(segs[i]);
			}
		}
		return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
	}

	/**
	 * Function to return a platform URI from a standard hierarchital URI.
	 * Normally we can use URI.createPlatformURI, but that function always assumes
	 * that it is non-platform
	 */
	public static URI getPlatformURI(URI uri) {
		String str = uri.toString();
		if (str.startsWith("platform:")) return uri; //$NON-NLS-1$
		return URI.createPlatformResourceURI(uri.toString());
	}

	/* external fault handler helpers */

	public static boolean getShowFaultHandler(EditPart part) {
		if (part instanceof ScopeEditPart)
			return ((ScopeEditPart)part).getShowFaultHandler();
		else if (part instanceof InvokeEditPart)
			return ((InvokeEditPart)part).getShowFaultHandler();
		else if (part instanceof StartNodeEditPart)
			return ((StartNodeEditPart)part).getShowFaultHandler();
		return false;
	}

	public static void setShowFaultHandler(EditPart part, boolean show) {
		if (part instanceof ScopeEditPart)
			((ScopeEditPart)part).setShowFaultHandler(show);
		else if (part instanceof InvokeEditPart)
			((InvokeEditPart)part).setShowFaultHandler(show);
		else if (part instanceof StartNodeEditPart)
			((StartNodeEditPart)part).setShowFaultHandler(show);
	}

	/* external compensation handler helpers */

	public static boolean getShowCompensationHandler(EditPart part) {
		if (part instanceof ScopeEditPart)
			return ((ScopeEditPart)part).getShowCompensationHandler();
		else if (part instanceof InvokeEditPart)
			return ((InvokeEditPart)part).getShowCompensationHandler();
		return false;
	}

	public static boolean getShowTerminationHandler(EditPart part) {
		if (part instanceof ScopeEditPart)
			return ((ScopeEditPart)part).getShowTerminationHandler();
		return false;
	}

	public static void setShowCompensationHandler(EditPart part, boolean show) {
		if (part instanceof ScopeEditPart)
			((ScopeEditPart)part).setShowCompensationHandler(show);
		else if (part instanceof InvokeEditPart)
			((InvokeEditPart)part).setShowCompensationHandler(show);
	}

	public static void setShowTerminationHandler(EditPart part, boolean show) {
		if (part instanceof ScopeEditPart)
			((ScopeEditPart)part).setShowTerminationHandler(show);
	}

	/* external event handler helpers */

	public static boolean getShowEventHandler(EditPart part) {
		if (part instanceof ScopeEditPart)
			return ((ScopeEditPart)part).getShowEventHandler();
		else if (part instanceof StartNodeEditPart)
			return ((StartNodeEditPart)part).getShowEventHandler();
		return false;
	}

	public static void setShowEventHandler(EditPart part, boolean show) {
		if (part instanceof ScopeEditPart)
			((ScopeEditPart)part).setShowEventHandler(show);
		else if (part instanceof StartNodeEditPart)
			((StartNodeEditPart)part).setShowEventHandler(show);
	}

	/**
	 * Returns the extension file of the given BPEL file.
	 */
	public static IFile getBPELEXFile(IFile bpelFile) {
		IPath path = bpelFile.getFullPath().removeFileExtension().addFileExtension(IBPELUIConstants.EXTENSION_MODEL_EXTENSIONS);
		return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
	}

	/**
	 * Returns the artifacts WSDL of the given BPEL file.
	 */
	public static IFile getArtifactsWSDLFile(IFile bpelFile) {
		IPath wsdlPath = bpelFile.getFullPath().removeFileExtension();
		String fileName = wsdlPath.lastSegment() + "Artifacts"; //$NON-NLS-1$
		wsdlPath = wsdlPath.removeLastSegments(1).append(fileName);
		wsdlPath = wsdlPath.addFileExtension(IBPELUIConstants.EXTENSION_WSDL);
		return ResourcesPlugin.getWorkspace().getRoot().getFile(wsdlPath);
	}

	public static Image getImage(IMarker marker) {
	    Image img = ModelMarkerUtil.getImage(marker);
	    ImageData background = null;
	    if (img != null) {
	    	background = img.getImageData();
	    }
		if (background == null) {
			// Don't give up yet. If this is also a problem marker, we can find an image to
			// display...
			try {
				if (marker.isSubtypeOf(IMarker.PROBLEM)) {
					background = ImageUtils.getImage(marker).getImageData();
				}
			} catch (CoreException e) {
				BPELUIPlugin.log(e);
				return null;
			}
		}
		if (background == null) return null;
		String uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGETOPLEFT, ""); //$NON-NLS-1$
		ImageData topLeft = getImageData(uri);
		uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGETOPRIGHT, ""); //$NON-NLS-1$
		ImageData topRight = getImageData(uri);
		uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGEBOTTOMLEFT, ""); //$NON-NLS-1$
		ImageData bottomLeft = getImageData(uri);
		uri = marker.getAttribute(IBPELUIConstants.MARKER_OVERLAYIMAGEBOTTOMRIGHT, ""); //$NON-NLS-1$
		ImageData bottomRight = getImageData(uri);
		OverlayCompositeImageDescriptor descriptor = new OverlayCompositeImageDescriptor(background, topLeft, topRight, bottomLeft, bottomRight);
		return descriptor.createImage();
	}

	private static ImageData getImageData(String uri) {
		if (uri.length() == 0) return null;
		URL url = null;
		try {
			url = new URL(uri);
		} catch (MalformedURLException e) {
			return null;
		}
		ImageDescriptor desc = ImageDescriptor.createFromURL(url);
		return desc.getImageData();
	}

	/**
	 * Returns the EditPart which is responsible for the given IFigure.
	 */
	public static EditPart mapFigure2EditPart(EditPartViewer viewer, IFigure figure) {
		Map visualPartMap = viewer.getVisualPartMap();
		EditPart part = null;
		while (part == null && figure != null) {
			part = (EditPart)visualPartMap.get(figure);
			figure = figure.getParent();
		}
		return part;
	}

	/**
	 * Reads the process from disk.
	 */
	public static Process getProcess(IResource bpelFile, ResourceSet resourceSet) throws IOException {
		URI uri = URI.createPlatformResourceURI(bpelFile.getFullPath().toString());
		Resource processResource = resourceSet.getResource(uri, true);
		EList<EObject> contents = processResource.getContents();
		if (!contents.isEmpty()) {
			return (Process) contents.get(0);
		}
		return null;
	}

	public static AccessibleEditPart getAccessibleEditPart(GraphicalEditPart part) {
		final GraphicalEditPart thisPart = part;

		return new AccessibleEditPart() {
				@Override
				public void getName(AccessibleEvent e) {
					String childType = null;
					String displayName = null;
					ILabeledElement labeledElement = BPELUtil.adapt(thisPart.getModel(), ILabeledElement.class);
					if (labeledElement != null) {
						childType = labeledElement.getTypeLabel(thisPart.getModel());
						displayName = labeledElement.getLabel(thisPart.getModel());
						if (childType != null && displayName.equals(childType)) {
							childType = null;
						}
					} else {
						e.result = null;
						return;
					}

					// return something reasonable (type followed by name if any)
					// or nothing at all

					StringBuffer concat = new StringBuffer();
					if (childType != null && childType.length() > 0)
						concat.append(childType);
					if (concat.length() > 0)
						concat.append(" "); //$NON-NLS-1$
					if (displayName != null && displayName.length() > 0)
						concat.append(displayName);
					if (concat.length() > 0)
						e.result = concat.toString();
					else
						e.result = null;
					return;
				}

				@Override
				public void getChildCount(AccessibleControlEvent e) {
					List<EditPart> list = thisPart.getChildren();
					int count = 0;
					for (EditPart part : list) {
						AccessibleEditPart access = (AccessibleEditPart)part.getAdapter(AccessibleEditPart.class);
						if (access == null)
							continue;
						count++;
					}
					e.detail = count;
				}

				@Override
				public void getChildren(AccessibleControlEvent e) {
					List<EditPart> list = thisPart.getChildren();
					Vector<Integer> childList = new Vector<Integer>();
					for (EditPart part : list) {
						AccessibleEditPart access = (AccessibleEditPart)part.getAdapter(AccessibleEditPart.class);
						if (access == null)
							continue;
						childList.add( Integer.valueOf( access.getAccessibleID()));
					}
					e.children = childList.toArray();
				}

				@Override
				public void getLocation(AccessibleControlEvent e) {
					Rectangle bounds = thisPart.getFigure().getBounds().getCopy();
					thisPart.getFigure().translateToAbsolute(bounds);
					org.eclipse.swt.graphics.Point p = new org.eclipse.swt.graphics.Point(0, 0);
					p = thisPart.getViewer().getControl().toDisplay(p);
					e.x = bounds.x + p.x;
					e.y = bounds.y + p.y;
					e.width = bounds.width;
					e.height = bounds.height;
				}

				/**
				 * @see AccessibleEditPart#getState(AccessibleControlEvent)
				 */
				@Override
				public void getState(AccessibleControlEvent e) {
					e.detail = ACC.STATE_SELECTABLE | ACC.STATE_FOCUSABLE;
					if (thisPart.getSelected() != EditPart.SELECTED_NONE)
						e.detail |= ACC.STATE_SELECTED;
					if (thisPart.getViewer().getFocusEditPart() == thisPart)
						e.detail = ACC.STATE_FOCUSED;
				}
			};
	}


	/** creates a table cursor that can be used to navigate tables for keyboard accessibility **/

	public static TableCursor createTableCursor(final Table table, final TableViewer tableViewer) {
		// create a TableCursor to navigate around the table
		final TableCursor cursor = new TableCursor(table, SWT.NONE);
		cursor.addSelectionListener(new SelectionAdapter() {
			// when the TableEditor is over a cell, select the corresponding row in the table
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (cursor.getRow() != null)
					table.setSelection(new TableItem[] {cursor.getRow()});
			}
			// when the user hits "ENTER" in the TableCursor, pop up an editor
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				TableItem row = cursor.getRow();
				if (row != null) {
					int nRow = table.indexOf(row);
					int column = cursor.getColumn();
					Object obj = tableViewer.getElementAt(nRow);
					tableViewer.editElement(obj, column);
				}
			}
		});

		// Hide the TableCursor when the user hits the "CTRL" or "SHIFT" key.
		// This alows the user to select multiple items in the table.
		cursor.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if ((e.keyCode == SWT.CTRL) || (e.keyCode == SWT.SHIFT)	||
					(e.stateMask & SWT.CONTROL) != 0	|| (e.stateMask & SWT.SHIFT) != 0) {
					cursor.setVisible(false);
				}
			}
		});

		cursor.addMouseListener(new MouseListener() {
			@Override
			public void mouseDoubleClick(MouseEvent e) { }
			@Override
			public void mouseDown(MouseEvent e) {
				TableItem row = cursor.getRow();
				if (row != null) {
					int nRow = table.indexOf(row);
					int column = cursor.getColumn();
					Object obj = tableViewer.getElementAt(nRow);
					tableViewer.editElement(obj, column);
				}
			}
			@Override
			public void mouseUp(MouseEvent e) {
			}
		});

		// Show the TableCursor when the user releases the "SHIFT" or "CTRL" key.
		// This signals the end of the multiple selection task.
		table.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				if (e.keyCode == SWT.CONTROL && (e.stateMask & SWT.SHIFT) != 0)
					return;
				if (e.keyCode == SWT.SHIFT && (e.stateMask & SWT.CONTROL) != 0)
					return;
				if (e.keyCode != SWT.CONTROL && (e.stateMask & SWT.CONTROL) != 0)
					return;
				if (e.keyCode != SWT.SHIFT && (e.stateMask & SWT.SHIFT) != 0)
					return;

				if (table.getItemCount() == 0)
					return;
				TableItem[] selection = table.getSelection();
				TableItem row = (selection.length == 0) ? table.getItem(table.getTopIndex()) : selection[0];
				table.showItem(row);
				cursor.setSelection(row, 0);
				cursor.setVisible(true);
				cursor.setFocus();
			}
		});
		return cursor;
	}

	public static ResourceSet createResourceSetImpl() {
		// TODO: Extensibility
		return new ResourceSetImpl();
	}

	static final NCNameWordDetector NCNAME_DETECTOR = new NCNameWordDetector ();

	/**
	 * Returns a validator that checks that the new value is a valid NCName.
	 */
	public static IInputValidator getNCNameValidator() {
		return new IInputValidator() {
			@Override
			public String isValid (String newText) {
				if ( NCNAME_DETECTOR.isValid( newText ) == false ) {
					return Messages.BPELUtil_NCName;
				}
				// TODO ! temporary hack
				return null;
			}
		};
	}

	public static void deleteNonContainmentRefs(EObject modelObject, Collection referents) {
		if (modelObject == null) return;
		for (EReference feature : modelObject.eClass().getEAllReferences()) {
			if (feature.isMany()) {
				EList<Object> list = (EList<Object>)modelObject.eGet(feature, true);
				for (Object referent : referents) {
					if (list.contains(referent)) list.remove(referent);
					// TODO: support non-changeable features!  print a warning.
				}
			} else {
				Object oldValue = modelObject.eGet(feature, true);
				for (Object referent : referents) {
					if (oldValue == referent) {
						if (feature.isUnsettable()) {
							// this is okay, default is always null for EReferences.
							modelObject.eUnset(feature);
						} else {
							modelObject.eSet(feature, null);
						}
						break;
					}
					// TODO: support non-changeable features!  print a warning.
				}
			}
		}
	}

	//@return:  returns arraylist with all activities the compensate
	//			can validly point to
	public static ArrayList getCompensableActivities(Object context){
		final ArrayList returnObjects = new ArrayList();
		if (context instanceof CompensateScope) {
			CompensateScope compensateScope = (CompensateScope) context;
			EObject enclosingContainer = compensateScope;
			if (compensateScope.eContainer() != null) {
				enclosingContainer = enclosingContainer.eContainer();
				// Go to parent scope where compensate is contained
				while (!(enclosingContainer instanceof Scope)
						&& (enclosingContainer.eContainer() != null)) {
					enclosingContainer = enclosingContainer.eContainer();
				}
			}

			// Put all scopes and invokes within parent scope in arraylist
			visitModelDepthFirst(enclosingContainer,
					new IModelVisitor() {
						@Override
						public boolean visit(Object modelObject) {
							if (modelObject instanceof Scope) {
								returnObjects.add(modelObject);
							} else if (modelObject instanceof Invoke) {
								returnObjects.add(modelObject);
							}
							return true;
						}
					});
			// https://issues.jboss.org/browse/JBIDE-8044
			if (!returnObjects.isEmpty())
				returnObjects.remove(0);	//remove the scope containing the compensate
			return returnObjects;
		}
		throw new IllegalArgumentException();
	}

	public static Object resolveXSDObject(Object xsdObject) {
		if (xsdObject instanceof XSDElementDeclaration) {
			XSDElementDeclaration resolvedElement = ((XSDElementDeclaration)xsdObject).getResolvedElementDeclaration();
			if (resolvedElement != null) xsdObject = resolvedElement;
		} else if (xsdObject instanceof XSDAttributeDeclaration) {
			XSDAttributeDeclaration resolvedAttribute = ((XSDAttributeDeclaration)xsdObject).getResolvedAttributeDeclaration();
			if (resolvedAttribute != null) xsdObject = resolvedAttribute;
		}
		return xsdObject;
	}

	public static String debugObject(Object object) {
		if (object == null) return "null"; //$NON-NLS-1$
		if (object instanceof String) { return "\""+(String)object+"\""; } //$NON-NLS-1$ //$NON-NLS-2$
		if (object.getClass().getName().startsWith("java.lang")) { //$NON-NLS-1$
			return object.toString();
		}
		if (object instanceof List) {
			StringBuffer b = new StringBuffer("("); //$NON-NLS-1$
			for (Iterator it = ((List)object).iterator(); it.hasNext(); ) {
				b.append(debugObject(it.next()));
				if (it.hasNext()) b.append(", "); //$NON-NLS-1$
			}
			b.append(")"); //$NON-NLS-1$
			return b.toString();
		}
		if (object instanceof QName) {
			QName qname = (QName)object;
			return "QName(\""+qname.getNamespaceURI()+"\", \""+qname.getLocalPart()+"\")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		StringBuffer b = new StringBuffer(shortClassName(object.getClass()));
		boolean proxy = (object instanceof EObject) && ((EObject)object).eIsProxy();
		if (proxy) b.append("-proxy"); //$NON-NLS-1$
		boolean isEObject = (object instanceof EObject);
		INamedElement namedElement = null;
		if (isEObject) {
			namedElement = BPELUtil.adapt(object, INamedElement.class);
			if (namedElement != null) {
				try {
					String s = namedElement.getName(object);
					b.append((s==null)? "<null>" : "<\""+s+"\">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				} catch (Exception e) {
					b.append("<???>"); //$NON-NLS-1$
				}
			}
		}
		if (namedElement==null) {
			b.append("{"); b.append(String.valueOf(object.hashCode())); b.append("}"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return b.toString();
	}

	public static String debug(Notification n) {
		StringBuffer b = new StringBuffer(shortClassName(n.getClass()));
		b.append("("); //$NON-NLS-1$
		b.append(debugObject(n.getNotifier()));
		b.append(", "); //$NON-NLS-1$
		switch (n.getEventType()) {
		case Notification.SET-1: b.append("CREATE"); break; //$NON-NLS-1$
		case Notification.SET: b.append("SET"); break; //$NON-NLS-1$
		case Notification.UNSET: b.append("UNSET"); break; //$NON-NLS-1$
		case Notification.ADD: b.append("ADD"); break; //$NON-NLS-1$
		case Notification.REMOVE: b.append("REMOVE"); break; //$NON-NLS-1$
		case Notification.ADD_MANY: b.append("ADD_MANY"); break; //$NON-NLS-1$
		case Notification.MOVE: b.append("MOVE"); break; //$NON-NLS-1$
		case Notification.REMOVING_ADAPTER: b.append("REMOVING_ADAPTER"); break; //$NON-NLS-1$
		case Notification.RESOLVE: b.append("RESOLVE"); break; //$NON-NLS-1$
		default: b.append("??? ("+String.valueOf(n.getEventType())+")"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		b.append(" "); //$NON-NLS-1$
		EStructuralFeature feature = (EStructuralFeature)n.getFeature();
		if (feature == null) b.append("???"); else b.append(feature.getName()); //$NON-NLS-1$
		if (n.getPosition() >= 0) {
			b.append("["); //$NON-NLS-1$
			b.append(String.valueOf(n.getPosition()));
			b.append("]"); //$NON-NLS-1$
		} else {
			if (feature != null && feature.isMany()) b.append("{***}"); //$NON-NLS-1$
		}
		b.append(": "); //$NON-NLS-1$
		b.append(debugObject(n.getOldValue()));
		b.append(" --> "); //$NON-NLS-1$
		b.append(debugObject(n.getNewValue()));
		b.append(")"); //$NON-NLS-1$
		return b.toString();

	}
	protected static String shortClassName(Class clazz) {
		StringBuffer b = new StringBuffer(clazz.getName());
		for (int i = b.indexOf("."); i >= 0; i = b.indexOf(".")) b.delete(0,i+1); //$NON-NLS-1$ //$NON-NLS-2$
		//if (b.indexOf("Impl") == b.length()-4) b.delete(b.length()-4, b.length()));
		return b.toString();
	}

	/**
	 * Creates a composite with a flat border around it.
	 */
	public static Composite createBorderComposite(Composite parent, TabbedPropertySheetWidgetFactory wf) {
		final Composite result = wf.createComposite(parent);
		FillLayout layout = new FillLayout();
		final int margin = 1;
		layout.marginHeight = margin;
		layout.marginWidth = margin;
		result.setLayout(layout);
		result.addPaintListener(new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				org.eclipse.swt.graphics.Rectangle bounds = result.getBounds();
				bounds.x = margin-1;
				bounds.y = margin-1;
				bounds.width = bounds.width - (margin*2) + 1;
				bounds.height = bounds.height - (margin*2) + 1;
				e.gc.drawRectangle(bounds);
			}
		});
		return result;
	}

	static void addVariablesToMap(Map<String, Variable> targetMap, Variables vars, Variable refVar ) {
		if (vars == null) {
			return;
		}
		for(Variable v : vars.getChildren()) {
			// scoping for initialization (only visible from).
			if (v == refVar) {
				break;
			}
			if (v.getName() != null) {
				targetMap.put(v.getName(),v);
			}
		}
	}


	static void addVisibleVariables (Map<String,Variable> targetMap, EObject target, Variable refVariable ) {
		if (target == null) {
			return;
		}
		if (target instanceof Resource) {
			return;
		}

		if (target instanceof Process) {
			addVariablesToMap(targetMap, ((Process)target).getVariables(), refVariable );
			return ;
		}
		// recursively add less local variables first
		addVisibleVariables(targetMap, target.eContainer(), refVariable );

		if (target instanceof Scope) {
			addVariablesToMap(targetMap, ((Scope)target).getVariables(), refVariable );
		}
		if (target instanceof Catch) {
			Variable v = ((Catch)target).getFaultVariable();
			if (v != null && v.getName() != null) {
				targetMap.put(v.getName(), v);
			}
		}
		if (target instanceof OnEvent) {
			Variable v = ((OnEvent)target).getVariable();
			if (v != null && v.getName() != null) {
				targetMap.put(v.getName(), v);
			}
		}

		if (target instanceof ForEach) {
			Variable v = ((ForEach)target).getCounterName();
			if (v != null && v.getName() != null) {
				targetMap.put(v.getName(), v);
			}
		}
	}

	private static void addPartnerLinksToMap(Map<String, PartnerLink> targetMap, PartnerLinks plinks) {
		if (plinks == null) return;
		for (PartnerLink p : plinks.getChildren()) {
			if (p.getName() != null) targetMap.put(p.getName(), p);
		}
	}
	private static void addVisiblePartnerLinks(Map<String, PartnerLink> targetMap, EObject target) {
		if (target == null) return;
		if (target instanceof Resource) return;
		if (target instanceof Process) {
			addPartnerLinksToMap(targetMap, ((Process)target).getPartnerLinks());
		} else {
			// recursively add less local partnerlinks first
			addVisiblePartnerLinks(targetMap, target.eContainer());
			if (target instanceof Scope) {
				addPartnerLinksToMap(targetMap, ((Scope)target).getPartnerLinks());
			}
		}
	}

	private static void addCorrelationSetsToMap(Map<String, CorrelationSet> targetMap, CorrelationSets csets) {
		if (csets == null) return;
		for( CorrelationSet c : csets.getChildren() ) {
			if (c.getName() != null) targetMap.put(c.getName(), c);
		}
	}
	private static void addVisibleCorrelationSets(Map<String, CorrelationSet> targetMap, EObject target) {
		if (target == null) return;
		if (target instanceof Resource) return;
		if (target instanceof Process) {
			addCorrelationSetsToMap(targetMap, ((Process)target).getCorrelationSets());
		} else {
			// recursively add less local correlationsets first
			addVisibleCorrelationSets(targetMap, target.eContainer());
			if (target instanceof Scope) {
				addCorrelationSetsToMap(targetMap, ((Scope)target).getCorrelationSets());
			}
		}
	}

	/**
	 * Look up the variables visible to a certain context activity (or the whole process).
	 * Variables in BPEL follow lexical scoping rules (resolved OASIS issue 101).
	 *
	 * The returned variables are in no particular order.
	 */
	public static Variable[] getVisibleVariables (EObject target) {

		Map<String,Variable> name2Variable = new HashMap<String,Variable>();

		addVisibleVariables(name2Variable, target,  target instanceof Variable ? (Variable) target: null );

		if (name2Variable.isEmpty()) {
			return EMPTY_VARIABLE_ARRAY;
		}

		Collection<Variable> variables =  name2Variable.values();
		if (variables.size() == 1) {
			return variables.toArray(EMPTY_VARIABLE_ARRAY);
		}
		ArrayList<Variable> list = new ArrayList<Variable>( variables );
		Collections.sort(list, new Comparator<Variable>() {
			@Override
			public int compare(Variable o1, Variable o2) {
				return o1.getName().compareTo(o2.getName());
			}
		});
		return list.toArray(EMPTY_VARIABLE_ARRAY);
	}

	/**
	 * Look up the PartnerLinks visible to a certain context activity (or the whole process).
	 * When local PartnerLinks are added to the spec, they will follow lexical scoping rules
	 * just like variables.
	 *
	 * The returned PartnerLinks are in no particular order.
	 */
	public static PartnerLink[] getVisiblePartnerLinks(EObject target) {
		Map<String, PartnerLink> name2PartnerLink = new HashMap<String, PartnerLink>();
		addVisiblePartnerLinks(name2PartnerLink, target);
		if (name2PartnerLink.isEmpty()) return EMPTY_PARTNERLINK_ARRAY;
		PartnerLink[] result = new PartnerLink[name2PartnerLink.size()];
		name2PartnerLink.values().toArray(result);
		return result;
	}

	/**
	 * Look up the PartnerLinks visible to a certain context activity (or the whole process).
	 * When local PartnerLinks are added to the spec, they will follow lexical scoping rules
	 * just like variables.
	 *
	 * The returned PartnerLinks are in no particular order.
	 */
	public static CorrelationSet[] getVisibleCorrelationSets(EObject target) {
		Map<String, CorrelationSet> name2CorrelationSet = new HashMap<String, CorrelationSet>();
		addVisibleCorrelationSets(name2CorrelationSet, target);
		if (name2CorrelationSet.isEmpty()) return EMPTY_CORRELATIONSET_ARRAY;
		CorrelationSet[] result = new CorrelationSet[name2CorrelationSet.size()];
		name2CorrelationSet.values().toArray(result);
		return result;
	}

	/**
	 * If the given message is used by an operation in the same definition,
	 * returns the Operation that uses the given message.
	 * Otherwise, returns null.
	 */
	public static Operation getOperationFromMessage(Message message) {
		if (message == null) return null;
		Definition def = message.getEnclosingDefinition();
		if (def == null) return null;
		Iterator<PortType> ptIt = def.getEPortTypes().iterator();
		while (ptIt.hasNext()) {
			PortType pt = ptIt.next();
			Iterator<Operation> it = pt.getOperations().iterator();
			while (it.hasNext()) {
				Operation op = it.next();
				Input input = op.getEInput();
				if (input != null) {
					if (input.getMessage().getQName().equals(message.getQName())) {
						return op;
					}
				}
				Output output = op.getEOutput();
				if (output != null) {
					if (output.getMessage().getQName().equals(message.getQName())) {
						return op;
					}
				}
				Iterator<Fault> faultIterator = op.getEFaults().iterator();
				while (faultIterator.hasNext()) {
					Fault fault = faultIterator.next();
					Message faultMessage = fault.getEMessage();
					if (faultMessage != null) {
						if (faultMessage.getQName() != null) {
							if (faultMessage.getQName().equals(message.getQName())) {
								return op;
							}
						}
					}
				}
			}
		}
		return null;
	}

	public static void openEditor(EObject modelObject, BPELEditor editor) {
		try {
			// https://issues.jboss.org/browse/JBIDE-8044
			if (modelObject==null) {
				// https://issues.jboss.org/browse/JBIDE-8601
				MessageDialog.openError(editor.getEditorSite().getShell(),
						Messages.BPELUtil__Error,
						Messages.BPELUtil_NoEditorForNullObject);
				return;
			}

			EObject resolvedObject = null;
			if (modelObject.eResource()==null) {
				// https://jira.jboss.org/browse/JBIDE-7351
				// try to resolve proxies here, otherwise we don't know editor input
				if (modelObject.eIsProxy()) {
					resolvedObject = EmfModelQuery.resolveProxy(editor.getProcess(), modelObject);
				}
			}
			else
				resolvedObject = modelObject;

			if (resolvedObject==null) {
				// https://issues.jboss.org/browse/JBIDE-8601
				MessageDialog.openError(editor.getEditorSite().getShell(),
						Messages.BPELUtil__Error, NLS.bind(
								Messages.BPELUtil_NoEditorForObject,
								(new Object[] { modelObject.getClass().getSimpleName() })));
				return;
			}
			IFile file = BPELUtil.getFileFromURI(resolvedObject.eResource().getURI());
			IDE.openEditor(editor.getSite().getWorkbenchWindow().getActivePage(), file);
		} catch (PartInitException ex) {
			BPELUIPlugin.log(ex, IStatus.WARNING);
		}
	}

	/**
	 * Returns the BPEL file associated with the given process.
	 */
	public static IFile getBPELFile(Process process) {
		return getFileFromURI(process.eResource().getURI());
	}



	public static String lookupOrCreateNamespacePrefix ( EObject context, String namespace, String prefix, Shell shell ) {

		String nsPrefix = BPELUtils.getNamespacePrefix(context, namespace);
		if (nsPrefix != null && nsPrefix.length() > 0) {
			return nsPrefix;
		}

		NamespaceMappingDialog dialog = new NamespaceMappingDialog (shell, context);
		dialog.setNamespace(namespace);
		if (prefix != null) {
			dialog.setPrefix(prefix);
		}

		if (dialog.open() == Window.CANCEL) {
			return nsPrefix;
		}

		nsPrefix = dialog.getPrefix();
		BPELUtils.setNamespacePrefix(context, namespace, nsPrefix);
		return nsPrefix;
	}


	/**
	 * Traverses the root object and returns all objects under it that are of the same
	 * class or subclasses of "target".
	 */
	public static List<EObject> getAllEObjectsOfType(EObject root, EClass eClass) {
		List<EObject> allElems = new ArrayList<EObject>();
		for (TreeIterator<EObject> iter = root.eAllContents(); iter.hasNext();) {
			EObject element = iter.next();
			if (eClass.isSuperTypeOf(element.eClass()) ||
				element.eClass() == eClass) {
				allElems.add(element);
			}
		}
		return allElems;
	}


	public static boolean isBPELProject(IProject project){
		if (project == null) {
			return false;
		}
		if (ModuleCoreNature.isFlexibleProject(project)) {
			IFacetedProject fproj = null;
			try {
			    fproj = ProjectFacetsManager.create(project);
			} catch (CoreException e) {
				return false;
			}
			if (fproj.hasProjectFacet(getBPELFacetVersion())) {
				return true;
			}
		}
		return false;

	}

	public static IProjectFacetVersion getBPELFacetVersion() {
		IProjectFacet bpelFacet = ProjectFacetsManager.getProjectFacet(IBPELModuleFacetConstants.BPEL20_PROJECT_FACET);
		IProjectFacetVersion bpelFacetVersion = bpelFacet.getVersion(IBPELModuleFacetConstants.BPEL20_MODULE_VERSION);
		return bpelFacetVersion;
	}


	public static org.eclipse.core.resources.IContainer getBPELContentFolder(IProject project) {
		org.eclipse.core.resources.IContainer bpelContent = null;
		if (BPELUtil.isBPELProject(project)) {
			IPath rootPath = getWebContentRootPath(project);
			if (rootPath != null && !rootPath.isEmpty()) {
				bpelContent = project.getFolder(rootPath);
			}
		}
		return bpelContent;
	}

	public static IPath getWebContentRootPath(IProject project) {
		IPath path = null;
		IVirtualComponent component = ComponentCore.createComponent(project);
		if (component != null && component.exists()) {
			path = component.getRootFolder().getProjectRelativePath();
		}
		return path;
	}
}