/*******************************************************************************
 * Copyright (c) 2005, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     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;
	}
}