/******************************************************************************
 * Copyright (c) 2002, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.common.core.service;

import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.gmf.runtime.common.core.internal.CommonCorePlugin;
import org.eclipse.gmf.runtime.common.core.internal.CommonCoreStatusCodes;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.osgi.framework.Bundle;

import com.ibm.icu.util.StringTokenizer;

/**
 * Concrete subclasses can be used to assist in parsing service provider
 * descriptors to filter out and delay loading of service providers that do not
 * apply.
 * <P>
 * This abstract class contains a set of useful utilities for such concrete
 * subclasses.
 * 
 * @author melaasar, mmostafa
 */
public class AbstractProviderConfiguration {
	/**
	 * The name of the 'object' XML attribute.
	 */
	protected static final String OBJECT = "object"; //$NON-NLS-1$
	
	/**
	 * The name of the 'id' XML attribute.
	 */
	protected static final String ID = "id"; //$NON-NLS-1$
	
	/**
	 * The name of the 'class' XML attribute.
	 */
	protected static final String CLASS = "class"; //$NON-NLS-1$
 
	/**
	 * The name of the 'method' XML attribute.
	 */
	protected static final String METHOD = "method"; //$NON-NLS-1$
	
	/**
	 * The name of the 'method' XML attribute.
	 */
	protected static final String STATIC_METHOD = "staticMethod"; //$NON-NLS-1$
	
	/**
	 * The name of the 'name' XML attribute.
	 */
	protected static final String NAME = "name"; //$NON-NLS-1$
	
	/**
	 * The name of the 'value' XML attribute.
	 */
	protected static final String VALUE = "value"; //$NON-NLS-1$
	
	/**
	 * The name of the 'notValue' XML attribute.
	 */
	protected static final String NOT_VALUE = "notValue"; //$NON-NLS-1$

	/**
	 * The name of the 'null' XML attribute value.
	 */
	protected static final String NULL = "null"; //$NON-NLS-1$
	
	/**
	 * the name of the context param
	 */
	protected static final String contextParam = "%Context"; //$NON-NLS-1$

	/**
	 * A map to store previously successful class lookups.
	 */
	private static Map isAssignableTable = new HashMap();

	/** 
	 * A map to store previously failed class lookups.
	 */
	private static Map isNotAssignableTable = new HashMap();
    
    /**
     * A map to hold the bundle to exception list
     */
    private static Map bundleToExceptionsSetMap = new HashMap();	
	/**
	 * a map of classes that get asked for methods they do not contain, by
	 * the provider, the map is a class to a Set of method signatures
	 */
	private static ClassToMethodSignaturesSetMap passiveClasses = 
		new ClassToMethodSignaturesSetMap();
	
	/**
	 * a class to cach passive classes, passive classes are the classes we asked 
	 * for a method with a specific signature and they faild to find it. The cach used 
	 * so in the next time we can tell if the method does not exists oin the class
	 * without calling getMethod by reflection, which improves the performance
	 * @author mmostafa
	 *
	 */
	private static class ClassToMethodSignaturesSetMap{
		
		/**
		 * internal map for the cach, it is a map of Class to Set of method signature Strings
		 */
		Map classToMethodSignaturesSetMap = new HashMap();
		
		/**
		 * adds a class and a method signature to the passive class cach
		 * @param clazz		the class
		 * @param signature	the method signature
		 */
		public void addMethod(Class clazz, String signature){
			Set signatures = (Set)classToMethodSignaturesSetMap.get(clazz);
			if (signatures==null){
				signatures = new HashSet();
				classToMethodSignaturesSetMap.put(clazz,signatures);
			}
			signatures.add(signature);
		}
		
		/**
		 * check if the class and the method signatrue are contained in the apssive collection,
		 * which means we do  need need to call get method oon the class becuase we will not 
		 * find it, this helps improving the performance.
		 * @param clazz
		 * @param signature
		 * @return
		 */
		public boolean contains(Class clazz, String signature){
			Set signatures = (Set)classToMethodSignaturesSetMap.get(clazz);
			if (signatures==null)
				return false;
			return signatures.contains(signature);
		}
	}
	
	/**
	 * internal class used to cach Methods, so we do not call getMethod too often 
	 * @author mmostafa
	 *
	 */
	private static class ClassToMethodSignatureToMethodCach{
		
		/**
		 * internal map to hold the cached data, it is a map of Class => Map
		 * of Singature string => method
		 */
		Map classToMethodSignatureToMethod = new HashMap();
		
		/**
		 * adds a <code>Method</code> to the cach
		 * @param clazz		the class we got the method from 
		 * @param methodSignature	the method signature
		 * @param method	the <code>Method</code>
		 */
		public void addMethod(Class clazz,String methodSignature, Method method ){
			Map signatureToMethodMap = (Map)classToMethodSignatureToMethod.get(clazz);
			if (signatureToMethodMap==null){
				signatureToMethodMap = new HashMap();
				classToMethodSignatureToMethod.put(clazz,signatureToMethodMap);
			}
			signatureToMethodMap.put(methodSignature,method);
		}
		
		/**
		 * gets a method from the cach using the class that owns it and the method 
		 * signature.
		 * @param clazz		the class that owns the method
		 * @param methodSignature	the method signature
		 * @return	the <code>Method</code> if found any, otherwise null
		 */
		public Method getMethod(Class clazz,String methodSignature){
			Map signatureToMethodMap  = (Map)classToMethodSignatureToMethod.get(clazz);
			if (signatureToMethodMap !=null){
				return (Method)signatureToMethodMap.get(methodSignature);
			}
			return null;
		}
		
	}
	
	/**
	 * map for class to Method signature to method cach
	 */
	private static ClassToMethodSignatureToMethodCach
		classToMethodSignatureToMethodCach = new ClassToMethodSignatureToMethodCach();
	
	
	
	/**
	 * Gets the class name of <code>object</code>.
	 * @param object the object for which the class name is to be found.
	 * @return the class name
	 */
	static String getClassName( Object object ) {
	    String cn = object.getClass().getName();
	    return cn.substring( cn.lastIndexOf('.')+1);
	}
	
	/**
	 * A descriptor for an XML configuration element that identifies a class by
	 * name and optionally its methods.
	 */
	public static class ObjectDescriptor {
		/** 
		 * The name of the class.
		 */
		private String contextClassName;
		
		/**
		 * The ID of the plugin that contains the class.
		 */
		private String contextClassPlugin;
		
		/**
		 * <code>true</code> if a syntax error has occurred,
		 * <code>false</code> otherwise.
		 */ 
		private boolean syntaxError; 
		
		/**
		 * A list of method descriptors for the class.
		 */
		private final List methods;
		
		/**
		 * A list of method descriptors for the class.
		 */
		private final List staticMethods;

		/**
		 * Creates a new object descriptor from its configuration element.
		 * 
		 * @param configElement
		 *            The configuration element.
		 */
		public ObjectDescriptor(IConfigurationElement configElement) {
			this(configElement, CLASS);
		}

		/**
		 * Creates a new object descriptor from its configuration element.
		 * 
		 * @param configElement
		 *            The configuration element.
		 * @param classNameTag
		 *            The name of the 'class' XML attribute.
		 */
		public ObjectDescriptor(
			IConfigurationElement configElement,
			String classNameTag) {

			 String s = configElement.getAttribute(classNameTag);
			 if (s != null) {
				 int start = s.indexOf("(");//$NON-NLS-1$
				 if (start != -1) {
					contextClassName = s.substring(0, start).trim();
				 	int end = s.indexOf(")");//$NON-NLS-1$
					if (end != -1 && end > start+1)
						contextClassPlugin = s.substring(start+1, end);
				 } else
					contextClassName = s.trim();
			 }

			 IConfigurationElement[] methodConfigs =
				configElement.getChildren(METHOD);
			 
			 IConfigurationElement[] staticMethodConfigs =
				configElement.getChildren(STATIC_METHOD);

			if (methodConfigs.length != 0) {
				methods = new ArrayList(methodConfigs.length);
				for (int i = 0; i < methodConfigs.length; i++) {
					String name = methodConfigs[i].getAttribute(NAME);
					if (name != null) {
						try {
							MethodDescriptor methodDescriptor =
								new MethodDescriptor(name);
							ValueDescriptor value =
								new ValueDescriptor(methodConfigs[i]);
							if (value != null)
								methods.add(new MethodValueEntry(methodDescriptor, value));
						} catch (Exception e) {
							syntaxError = true;
							Log.error(CommonCorePlugin.getDefault(), CommonCoreStatusCodes.SERVICE_FAILURE,	configElement.getDeclaringExtension().getContributor().getName()+ ".plugin.xml extension [" + configElement.getDeclaringExtension().getExtensionPointUniqueIdentifier() + "]: invalid syntax for method [" + name + "]");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						}
					} else {
						syntaxError = true;
						Log.error(CommonCorePlugin.getDefault(), CommonCoreStatusCodes.SERVICE_FAILURE,	configElement.getDeclaringExtension().getContributor().getName()+ ".plugin.xml extension [" + configElement.getDeclaringExtension().getExtensionPointUniqueIdentifier() + "] : missing method name");  //$NON-NLS-1$ //$NON-NLS-2$ 
					}
				}
			} 
			else
				methods = Collections.EMPTY_LIST;
			
			
			if (staticMethodConfigs.length != 0) {
				staticMethods = new ArrayList(staticMethodConfigs.length);
				for (int i = 0; i < staticMethodConfigs.length; i++) {
					String name = staticMethodConfigs[i].getAttribute(NAME);
					if (name != null) {
						try {
							StaticMethodDescriptor methodDescriptor =
								new StaticMethodDescriptor(name);
							ValueDescriptor value =
								new ValueDescriptor(staticMethodConfigs[i]);
							if (value != null)
								staticMethods.add(new MethodValueEntry(methodDescriptor, value));
						} catch (Exception e) {
							syntaxError = true;
							Log.error(CommonCorePlugin.getDefault(), CommonCoreStatusCodes.SERVICE_FAILURE,	configElement.getDeclaringExtension().getContributor().getName()+ ".plugin.xml extension [" + configElement.getDeclaringExtension().getExtensionPointUniqueIdentifier() + "]: invalid syntax for method [" + name + "]");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						}
					} else {
						syntaxError = true;
						Log.error(CommonCorePlugin.getDefault(), CommonCoreStatusCodes.SERVICE_FAILURE,	configElement.getDeclaringExtension().getContributor().getName()+ ".plugin.xml extension [" + configElement.getDeclaringExtension().getExtensionPointUniqueIdentifier() + "] : missing method name");  //$NON-NLS-1$ //$NON-NLS-2$ 
					}
				}
			}else
				staticMethods = Collections.EMPTY_LIST;
			
			
			
			if (contextClassName != null)
				contextClassName = contextClassName.intern();
			if (contextClassPlugin != null)
				contextClassPlugin = contextClassPlugin.intern();
		}

		/**
		 * Tests if the object descriptor applies to the given context object.
		 * 
		 * @param object
		 *            The context object.
		 * @return <code>true</code> if it applies; <code>false</code>
		 *         otherwise
		 */
		public boolean sameAs(Object object) {
			if (syntaxError)
				return false;

			Object targetObject = object;
			if (contextClassName != null) {
				if (!isAssignableTo(object.getClass(), contextClassName)) {
					targetObject = getAdapter(object, contextClassName, contextClassPlugin);
					if (targetObject == null)
						return false;
				}
			} 
			
			for(Iterator iter = methods.iterator(); iter.hasNext();) {
				MethodValueEntry entry = (MethodValueEntry)iter.next();
				Object methodValue = invokeMethod(entry.method, targetObject);
				
				if (methodValue == null || !entry.value.sameAs(methodValue))
					return false;
			}
			
			for(Iterator iter = staticMethods.iterator(); iter.hasNext();) {
				MethodValueEntry entry = (MethodValueEntry)iter.next();
				Object methodValue = invokeStaticMethod((StaticMethodDescriptor)entry.method, targetObject);
				
				if (methodValue == null || !entry.value.sameAs(methodValue))
					return false;
			}
			
			return true;
		}
	}

	/**
	 * A descriptor for an XML configuration element that identifies a method by
	 * name and its formal parameters.
	 */
	private static class MethodDescriptor {
        
        protected String dataForIntialize = NULL;
		
		/**
		 * The method name.
		 */
		private String name;
		
		/**
		 * The array of method parameters.
		 */
		private Object parameterObjects[];
		
		/**
		 * The array of method parameter types.
		 */
		private Class parameterTypes[];
		
		/**
		 * The next cascading method descriptor.
		 */
		private MethodDescriptor next;

		/**
		 * The list of method parameters.
		 */
		private List parameters;
		
		/**
		 * the method signature
		 *
		 */
		private String signature = null;
		
		
		protected MethodDescriptor(){
			// empty 
		}

		/**
		 * Creates a new method descriptor from a string representing the
		 * method's full cascading invocation with parameters.
		 * <P>
		 * The format of the string is:
		 * <P>
		 * <code>method_name([params])[.method_name([params])]*</code>
		 * <P>
		 * Where:
		 * <UL>
		 * <LI>the <i>params </i> are comma-separated string literals without
		 * double quotes.</LI>
		 * <LI>only string <i>params </i> are allowed (no texual representation
		 * of non-string params are allowed)</LI>
		 * </UL>
		 * <P>
		 * For example:
		 * <P>
		 * <code>getPropertyValue(Source_Connection).getName()</code>
		 * 
		 * @param string
		 *            the method invocation string
		 */
		public MethodDescriptor(String string) {
            dataForIntialize = string;
		}
        
        protected boolean isInitialized(){
            return (dataForIntialize==null);
        }

        protected void initialize() {
            //check if already initialized
            if (isInitialized())
                return;
            try {
                // set method name
                dataForIntialize = parseName(dataForIntialize.trim());
    			// set method parameters
                dataForIntialize = parseParameterList(dataForIntialize.trim());
    
    			// fill the parameter objects and types arrays
    			if (parameters != null && !parameters.isEmpty()) {
    				Collections.reverse(parameters);
    				parameterObjects = parameters.toArray();
    				parameterTypes = new Class[parameterObjects.length];
    				for (int i = 0; i < parameterObjects.length; i++) {
    					String p = (String) parameterObjects[i];
    					int objIndex = p.indexOf("[object]"); //$NON-NLS-1$
    					boolean isObject = objIndex >= 0;
    					int parseAsIndex = p.indexOf(":::"); //$NON-NLS-1$
    					try {
    						if (isObject && (parseAsIndex >= 0))
    							// assume order: [object] before type:::param
    							assert (objIndex < parseAsIndex);
    						if (parseAsIndex >= 0) {
    							// "type:::param"
    							String parseAs =
    								p.substring((isObject ? 8 : 0), parseAsIndex);
    							String value =
    								p.substring(parseAsIndex + 3, p.length());
    							if (parseAs.equalsIgnoreCase("int")) { //$NON-NLS-1$
    								parameterTypes[i] = Integer.class;
    								parameterObjects[i] = Integer.decode(value);
    							} else if (parseAs.equalsIgnoreCase("bool")) { //$NON-NLS-1$
    								parameterTypes[i] = Boolean.class;
    								parameterObjects[i] = Boolean.valueOf(value);
    							} else if (parseAs.equalsIgnoreCase("double")) { //$NON-NLS-1$
    								parameterTypes[i] = Double.class;
    								parameterObjects[i] = Double.valueOf(value);
    							}
    							// if [object] present, set type to Object
    							if (isObject)
    								parameterTypes[i] = Object.class;
    						} else if (isObject) { // "[object]param"
    							String value = p.substring(8, p.length());
    							parameterTypes[i] = Object.class;
    							parameterObjects[i] = value;
    						} else // "param"
    							parameterTypes[i] = String.class;
    					} catch (Exception e) {
    						String value =
    							p.substring(
    								((parseAsIndex >= 0) ? parseAsIndex + 3 : 0),
    								p.length());
    						parameterObjects[i] = value;
    						parameterTypes[i] = String.class;
    					}
    				}
    			}
    			parameters = null;
    
    			// set method parameters
    			if (dataForIntialize.length() != 0) {
    				if (dataForIntialize.charAt(0) != '.')
    					throw new IllegalArgumentException();
    				next = new MethodDescriptor(dataForIntialize.substring(1).trim());
    			}
    			
    		 if (this.name != null)
    				name = name.intern();
            }finally{
                dataForIntialize = null;
            }
        }

		/**
		 * Parses and returns the method name in a method invocation string.
		 * 
		 * @param string
		 *            the method invocation string
		 * @return the method name
		 */
		protected String parseName(String string) {
			int index = string.indexOf('(');
			if (index == -1)
				throw new IllegalArgumentException(); 
			name = string.substring(0, index).trim();
			return string.substring(index + 1);
		}

		/**
		 * Parses a method invocation string for the list of parameters, which
		 * are placed in the <code>parameters</code> field.
		 * 
		 * @param string
		 *            the method invocation string
		 * @return the end part of the method invocation string that has not
		 *         been parsed.
		 */
		protected String parseParameterList(String string) {
			int index = -1;
			String paramStr = null;
			while (paramStr == null) {
				index = string.indexOf(')', index + 1);
				if (index == -1)
					throw new IllegalArgumentException(); 
				if (index == 0 || string.charAt(index - 1) != '\\')
					paramStr = string.substring(0, index);
			}
			if (paramStr.length() != 0) {
				parameters = new ArrayList();
				parseParameters(paramStr.trim());
			}
			return string.substring(index + 1);
		}

		/**
		 * Parses a string containing a list of method parameters and stores
		 * them in the <code>parameters</code> field.
		 * 
		 * @param string
		 *            the comma-separated list of method parameters.
		 */
		private void parseParameters(String string) {
			int index = string.indexOf(',');
			if (index != -1 && string.charAt(index - 1) != '\\') {
				parseParameters(string.substring(index + 1).trim());
				parameters.add(string.substring(0, index));
			} else
				parameters.add(string);
		}

		/**
		 * Returns the method name.
		 * 
		 * @return the method name
		 */
		public String getName() {
			return name;
		}
		
		/**
		 * Sets the method name.
		 * @param the method name
		 */
		public void setName(String name) {
			this.name = name;
		}

		/**
		 * Returns an array of string params.
		 * 
		 * @return the parameters
		 */
		public Object[] getParameters() {
			return parameterObjects;
		}

		/**
		 * Returns an array of parameter classes.
		 * 
		 * @return the parameter types
		 */
		public Class[] getParameterTypes() {
			return parameterTypes;
		}
		
		/**
		 * sets the the array of params.
		 * @param paramters
		 */
		protected void setParameters(Object[] paramters) {
			parameterObjects = paramters;
		}

		/**
		 * sets the the array of parameter types.
		 * @param paramtersTypes
		 */
		public void setParameterTypes(Class[] paramterTypes) {
			this.parameterTypes = paramterTypes;
		}

		/**
		 * Returns the next cascading method descriptor, if any.
		 * 
		 * @return the next method descriptor, or <code>null</code> if there
		 *         is none
		 */
		public MethodDescriptor getNext() {
			return next;
		}
		
		/**
		 * sets the next cascading method descriptor, if any.
		 * @param next
		 */
		protected void setNext(MethodDescriptor next) {
			this.next = next;
		}

		/**
		 * Gets the Paramters List
		 * @return The list of method parameters.
		 */
		protected List getParamtersList(){
			return parameters;
		}
		
		/**
		 * utility method used to get the signature of the method this method descriptor
		 * descripe.
		 * @return the signature of the method
		 */
		public String getSignature(){
			if (this.signature==null){
				StringBuffer sb = 
					new StringBuffer();
				sb.append(name);
				sb.append('(');
				if(parameterTypes!=null)
					for(int index= 0 ; index < parameterTypes.length ; index++){
						Class clazz = parameterTypes[index];
						sb.append(clazz.getName());
						if(index<parameterTypes.length-1)
							sb.append(',');
					}
				sb.append(')');
				signature = sb.toString();
			}
			return signature;
			
		}
	}

	
	private static class StaticMethodDescriptor extends MethodDescriptor {
        
		/**
		 * the plugin Name
		 */
		private String pluginID;
		
		/**
		 * the Class Name
		 */
		private String className;
		
		/**
		 * Creates a new method descriptor from a string representing the
		 * method's full cascading invocation with parameters.
		 * <P>
		 * The format of the string is:
		 * <P>
		 * <code>PluginID\ClassName.method_name([params])[.method_name([params])]*</code>
		 * <P>
		 * Where:
		 * <UL>
		 * <LI>the <i>params </i> are comma-separated string literals without
		 * double quotes.</LI>
		 * <LI>only string <i>params </i> are allowed (no texual representation
		 * of non-string params are allowed)</LI>
		 * <LI>to identify a parameter as the current context you put %
		 * </UL>
		 * <P>
		 * For example:
		 * <P>
		 * <code>MyPluginID\MyClass.MyStaticFunction(%,"some value")</code>
		 * 
		 * @param string
		 *            the method invocation string
		 */
		public StaticMethodDescriptor(String string) {
            dataForIntialize = string;
		}
        
        public void initialize() {
            // check if already initialized
            if (isInitialized())
                return;
            try {
                // set plugin ID
                dataForIntialize = parsePluginID(dataForIntialize.trim());
    			// set class Name 
                dataForIntialize = parseClassName(dataForIntialize.trim());
    			// set method name
                dataForIntialize = parseName(dataForIntialize.trim());
    			// set method parameters
                dataForIntialize = parseParameterList(dataForIntialize.trim());
    
    			List parameters = getParamtersList();
    			
    			// fill the parameter objects and types arrays
    			if (parameters != null && !parameters.isEmpty()) {
    				Collections.reverse(parameters);
    				Object[] parameterObjects = parameters.toArray();
    				Class[] parameterTypes = new Class[parameterObjects.length];
    				for (int i = 0; i < parameterObjects.length; i++) {
    					String p = (String) parameterObjects[i];
    					int objIndex = p.indexOf("[object]"); //$NON-NLS-1$
    					boolean isObject = objIndex >= 0;
    					int parseAsIndex = p.indexOf(":::"); //$NON-NLS-1$
    					try {
    						if (isObject && (parseAsIndex >= 0))
    							// assume order: [object] before type:::param
    							assert (objIndex < parseAsIndex);
    						if (parseAsIndex >= 0) {
    							// "type:::param"
    							String parseAs =
    								p.substring((isObject ? 8 : 0), parseAsIndex);
    							String value =
    								p.substring(parseAsIndex + 3, p.length());
    							if (parseAs.equalsIgnoreCase("int")) { //$NON-NLS-1$
    								parameterTypes[i] = Integer.class;
    								parameterObjects[i] = Integer.decode(value);
    							} else if (parseAs.equalsIgnoreCase("bool")) { //$NON-NLS-1$
    								parameterTypes[i] = Boolean.class;
    								parameterObjects[i] = Boolean.valueOf(value);
    							} else if (parseAs.equalsIgnoreCase("double")) { //$NON-NLS-1$
    								parameterTypes[i] = Double.class;
    								parameterObjects[i] = Double.valueOf(value);
    							}
    							// if [object] present, set type to Object
    							if (isObject)
    								parameterTypes[i] = Object.class;
    						} else if (isObject) { // "[object]param"
    							String value = p.substring(8, p.length());
    							parameterTypes[i] = Object.class;
    							parameterObjects[i] = value;
    						} else if (p.startsWith(contextParam)){// "param" 
    							parameterTypes[i] = getParameterType(p);
    							parameterObjects[i] = "%Context"; //$NON-NLS-1$
    						}
    						else
    							parameterTypes[i] = String.class;
    					} catch (Exception e) {
    						String value =
    							p.substring(
    								((parseAsIndex >= 0) ? parseAsIndex + 3 : 0),
    								p.length());
    						parameterObjects[i] = value;
    						parameterTypes[i] = String.class;
    					}
    				}
    				setParameters(parameterObjects);
    				setParameterTypes(parameterTypes);
    			}
    			parameters = null;
    
    			// set method parameters
    			if (dataForIntialize.length() != 0) {
    				if (dataForIntialize.charAt(0) != '.')
    					throw new IllegalArgumentException();
    				setNext(new MethodDescriptor(dataForIntialize.substring(1).trim()));
    			}
    			
    		 if (getName() != null)
    				setName(getName().intern());
            }finally{
                dataForIntialize = null;
            }
        }

		
		/**
		 * parse the passed paramter to extract the paramter's class
		 * @param p		the parapemter 
		 * @return
		 */
		private Class getParameterType(String parameter) {
			int startIndex = parameter.indexOf("["); //$NON-NLS-1$
			int endIndex = parameter.indexOf("]"); //$NON-NLS-1$
			if(startIndex==-1 || endIndex==-1)
				throw new IllegalArgumentException(); 
			String parameterTypeString= parameter.substring(startIndex+1,endIndex).trim();
			
			endIndex = parameterTypeString.indexOf('/');
			if(endIndex==-1 || endIndex==parameterTypeString.length()-1)
				throw new IllegalArgumentException(); 
			String parameterPluginID = parameterTypeString.substring(0,endIndex).trim();
			String parameterClassName = parameterTypeString.substring(endIndex + 1);
			Class clazz = loadClass(parameterClassName,parameterPluginID);
			if(clazz==null)
				clazz =  Object.class;
			return clazz;
		}

		/**
		 * Parses and returns the Plugin ID in a method invocation string.
		 * 
		 * @param string
		 *            the method invocation string
		 * @return the plugin name
		 */
		private String parsePluginID(String string) {
			int index = string.indexOf('/');
			if (index == -1)
				throw new IllegalArgumentException(); 
			pluginID = string.substring(0, index).trim();
			return string.substring(index + 1);
		}
		
		/**
		 * Parses and returns the Plugin ID in a method invocation string.
		 * 
		 * @param string
		 *            the method invocation string
		 * @return the plugin name
		 */
		private String parseClassName(String string) {
			int index = string.indexOf('(');
			if (index == -1)
				throw new IllegalArgumentException(); 
			index = string.lastIndexOf('.',index);
			if (index == -1)
				throw new IllegalArgumentException(); 
			className = string.substring(0, index).trim();
			return string.substring(index + 1);
		}
		
	public String getPluginID(){
			return pluginID;
		}
		
		public String getClassName(){
			return className;
		}
	
	}
	
	
	/**
	 * A descriptor for an XML configuration element that identifies a method
	 * result by its type and <code>toString()</code> value.
	 */
	private static class ValueDescriptor {
		
		/**
		 * The valid value literals.
		 */
		private Set valueLiterals;
		
		/**
		 * The invalid valud literals.
		 */
		private Set notValueLiterals;
		
		/**
		 * The valid value objects.
		 */
		private List valueObjects;
		
		/**
		 * The invalid value objects.
		 */
		private List notValueObjects;

		/**
		 * Creates a new value descriptor from its configuration element.
		 * 
		 * @param configElement
		 *            The configuration element.
		 */
		public ValueDescriptor(IConfigurationElement configElement) {
			valueLiterals = new HashSet();
			String s = configElement.getAttribute(VALUE);
			if (s != null)
				parseValueLiteralString(s, valueLiterals);

			notValueLiterals = new HashSet();
			s = configElement.getAttribute(NOT_VALUE);
			if (s != null)
				parseValueLiteralString(s, notValueLiterals);

			IConfigurationElement[] valueConfigs = configElement.getChildren(VALUE);
			valueObjects = new ArrayList(valueConfigs.length);
			for (int i=0; i<valueConfigs.length; i++)
				valueObjects.add(new ObjectDescriptor(valueConfigs[i]));

			IConfigurationElement[] notValueConfigs = configElement.getChildren(NOT_VALUE);
			notValueObjects = new ArrayList(notValueConfigs.length);
			for (int i=0; i<notValueConfigs.length; i++)
				notValueObjects.add(new ObjectDescriptor(notValueConfigs[i]));
		}
		
		/**
		 * Parse the string <code>s</code>, which is a comma-separated list
		 * of value literals and place them in the given <code>list</code>.
		 * 
		 * @param s
		 *            the string to be parsed
		 * @param list
		 *            the set of literal string values from <code>s</code>.
		 */
		private void parseValueLiteralString(String s, Set list) {
			// parse the string comma-separated string literals ignoring escaped commas
			int start = 0;
			int end = s.indexOf(',');
			while (end != -1) {
				if (s.charAt(end-1) == '\\') {
					s = s.substring(0, end-1) + s.substring(end);
					end = s.indexOf(',', end);
					continue;
				}
				list.add(s.substring(start, end).trim().intern());
				start = end +1;
				end = s.indexOf(',', start);
			}
			list.add(s.substring(start).trim().intern());
		}
		
		/**
		 * Returns <code>true</code> if I am the same as <code>object</code>,
		 * <code>false</code> otherwise.
		 * 
		 * @param object
		 *            the object to be tested
		 * @return <code>true</code> if I am the same as <code>object</code>,
		 *         <code>false</code> otherwise.
		 */
		public boolean sameAs(Object object) {
			if (!valueLiterals.isEmpty()) {
				if (!valueLiterals.contains(object.toString()))
					return false;
			}
			if (!notValueLiterals.isEmpty()) {
				if (notValueLiterals.contains(object.toString()))
					return false;
			}
			if (!valueObjects.isEmpty()) {
				if (!isObjectinList(object, valueObjects))
					return false;
			}
			if (!notValueObjects.isEmpty()) {
				if (isObjectinList(object, notValueObjects))
					return false;
			}
			return true;
		}
		
		/**
		 * Answers whether or not an object in <code>list</code> is the
		 * {@link #sameAs(Object)}<code>object</code>.
		 * 
		 * @param object
		 *            the object to find
		 * @param list
		 *            the list of objects
		 * @return <code>true</code> if an object in <code>list</code> is
		 *         the {@link #sameAs(Object)}<code>object</code>,
		 *         <code>false</code> otherwise.
		 */
		private boolean isObjectinList(Object object, List list) {
			Iterator i = list.iterator();
			while (i.hasNext()) {
				if (((ObjectDescriptor)i.next()).sameAs(object))
					return true;
			}
			return false;
		}
	}

	/**
	 * Describes a method value using a method descriptor and a value descriptor.
	 */
	private static class MethodValueEntry {
		
		/**
		 * The method descriptor.
		 */
		public MethodDescriptor method;
		
		/**
		 * The value descriptor.
		 */
		public ValueDescriptor value;

		/**
		 * Creates a new method value entry.
		 * @param method the method descriptor
		 * @param value the value descriptor
		 */
		public MethodValueEntry(MethodDescriptor method, ValueDescriptor value) {
			super();
			this.method = method;
			this.value = value;
		}
	}

	/**
	 * A helper method to return a list of objects whose ids are given in a
	 * comma-separated string and whose instances are given in an object map.
	 * 
	 * @param objectsIds
	 *            A comma-separated object ids string
	 * @param objectMap
	 *            A map of object ids to their instances
	 * @param configElement
	 *            The configuration element, used for error logging
	 * @return a list of object instances whose ids are given or
	 *         <code>null</code> if no ids matched any instances
	 */
	protected static List getObjectList(String objectsIds, Map objectMap, IConfigurationElement configElement) {
		if (objectsIds == null)
			return null;
		StringTokenizer ids = new StringTokenizer(objectsIds.trim(), ","); //$NON-NLS-1$
		if (!ids.hasMoreTokens())
			return null;
		
		List objectList = new ArrayList();
		while (ids.hasMoreTokens()) {
			String objectId = ids.nextToken().trim();
			Object objectVal = objectMap.get(objectId);
			if (objectVal != null)
				objectList.add(objectVal);
			else {
				Log.error(CommonCorePlugin.getDefault(), CommonCoreStatusCodes.SERVICE_FAILURE, configElement.getDeclaringExtension().getContributor().getName()+ ".plugin.xml extension [" + configElement.getDeclaringExtension().getExtensionPointUniqueIdentifier() + "]: object id (" + objectId + ") is not in the list " + objectMap.keySet());  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
			}
		}
		return objectList;
	}

	/**
	 * Parses the comma-separated <code>s</code> string and returns a set of
	 * the individual entries in the string.
	 * 
	 * @param s
	 *            A comma-separated string
	 * @return a set of the individual entries in the string.
	 */
	protected static Set getStrings(String s) {
		if (s == null)
			return null;
		Set stringList = new HashSet();
		StringTokenizer ids = new StringTokenizer(s.trim(), ","); //$NON-NLS-1$
		while (ids.hasMoreTokens()) {
			stringList.add(ids.nextToken().trim());
		}
		return stringList.isEmpty() ? null : stringList;
	}

	/**
	 * Tests if an object matches at least one in the list of object descriptors
	 * passed.
	 * 
	 * @param object
	 *            the object for which to find a match
	 * @param objects
	 *            the list of object in which to find a match
	 * @return <code>true</code> if there was a match, <code>false</code>
	 *         otherwise
	 */
	protected static boolean objectMatches(Object object, List objects) {
		if (object != null) {
			for (Iterator i = objects.iterator(); i.hasNext();) {
				ObjectDescriptor desc = (ObjectDescriptor) i.next();
				if (desc.sameAs(object))
					return true;
			}
		}
		return false;
	}

	/**
	 * A utility method to load a class using its name and a given class loader.
	 * 
	 * @param className
	 *            The class name
	 * @param bundle
	 *            The class loader
	 * @return The loaded class or <code>null</code> if could not be loaded
	 */
	 /*protected static Class loadClass(String className, Bundle bundle) {
		try {
			return bundle.loadClass(className);
		} catch (ClassNotFoundException e) {
			return null;
		}
	}*/
	
	/**
	 * A utility method to load a class using its name and a given class loader.
	 * 
	 * @param className
	 *            The class name
	 * @param bundle
	 *            The class loader
	 * @return The loaded class or <code>null</code> if could not be loaded
	 */
	protected static Class loadClass(String className, String pluginId) {
		StringBuffer keyStringBuf = new StringBuffer(className.length()
			+ pluginId.length() + 2); // 2 is for . and extra.
		keyStringBuf.append(pluginId);
		keyStringBuf.append('.');
		keyStringBuf.append(className);
		String keyString = keyStringBuf.toString();
		WeakReference ref = (WeakReference) successLookupTable.get(keyString);
		Class found = (ref != null) ? (Class) ref.get()
			: null;
		if (found == null) {
			if (ref != null)
				successLookupTable.remove(keyString);
			if (!failureLookupTable.contains(keyString)) {
				try {
					Bundle bundle = basicGetPluginBundle(pluginId);
					if (bundle!=null){
                        // never load the class if the bundle is not active other wise
                        // we will cause the plugin to load
                        // unless the class is in the exception list
                        int state = bundle.getState();
                        if ( state == org.osgi.framework.Bundle.ACTIVE || isInExceptionList(bundle,className)){
    						found = bundle.loadClass(className);
    						successLookupTable.put(keyString, new WeakReference(found));
                            if (state == org.osgi.framework.Bundle.ACTIVE){
                                bundleToExceptionsSetMap.remove(bundle);
                            }
                        }
					}else{
						failureLookupTable.add(keyString);
					}
				} catch (ClassNotFoundException e) {
					failureLookupTable.add(keyString);
				}
			}
		}
		return found;
	}
	
	
	private static boolean isInExceptionList(Bundle bundle, String className) {
        String packageName = className.substring(0,className.lastIndexOf('.'));
        Set exceptionSet = (Set)bundleToExceptionsSetMap.get(bundle);
        if (exceptionSet==null){
            Dictionary dict = bundle.getHeaders();
            String value = (String)dict.get("Eclipse-LazyStart"); //$NON-NLS-1$
            if (value!=null){
                int index  = value.indexOf("exceptions"); //$NON-NLS-1$
                if (index!=-1){
                    try {
                        int start = value.indexOf('"',index+1);
                        int end = value.indexOf('"',start+1);
                        String exceptions = value.substring(start+1,end);
                        exceptionSet = new HashSet(2);
                        StringTokenizer tokenizer = new StringTokenizer(exceptions, ","); //$NON-NLS-1$
                        while (tokenizer.hasMoreTokens()) {
                            exceptionSet.add(tokenizer.nextToken().trim());
                        }
                    }catch(IndexOutOfBoundsException exception){
                        // this means the MF did not follow the documented format for the exceptions list
                        // so i'll consider it empty
                        exceptionSet = Collections.EMPTY_SET;
                    }
                    
                }else{
                    exceptionSet = Collections.EMPTY_SET;
                }
            }else{
                exceptionSet = Collections.EMPTY_SET;
            }
            bundleToExceptionsSetMap.put(bundle, exceptionSet);
        }
        return exceptionSet.contains(packageName);
    }

    /**
	 * Given a bundle id, it checks if the bundle is found and activated. If it
	 * is, the method returns the bundle, otherwise it returns <code>null</code>.
	 * 
	 * @param pluginId
	 *            the bundle ID
	 * @return the bundle, if found
	 */
	protected static Bundle getPluginBundle(String pluginId) {
		Bundle bundle = basicGetPluginBundle(pluginId);
		if (null != bundle && bundle.getState() == org.osgi.framework.Bundle.ACTIVE)
			return bundle;
		return null;
	}
    
    private static Bundle basicGetPluginBundle(String pluginId) {
        return Platform.getBundle(pluginId);   
    }

	/**
	 * Tests if the given class is assignable to the given class name. Optimized
	 * to look first in a cache of previously retrieved results.
	 * 
	 * @param clazz
	 *            the class to be tested
	 * @param className
	 *            the class name to test against
	 * @return <code>true</code> if the class is assignable to the class name,
	 *         <code>false</code> otherwise.
	 */
	protected static boolean isAssignableTo(Class clazz, String className) {
		if (clazz == null)
			return false;

		if ( contains(isNotAssignableTable, clazz, className) ) {
			return false;
		}
		
		if ( contains(isAssignableTable, clazz, className) ) {
			return true;
		}
	
		boolean result = isAssignableToNoCache(clazz,className);
		
		if (result) {
			add(isAssignableTable, clazz, className);
		} else {
			add(isNotAssignableTable, clazz, className);
		}

		return result;
	}

	/**
	 * Tests if the given class is assignable to the given class name.
	 * 
	 * @param clazz
	 *            the class to be tested
	 * @param className
	 *            the class name to test against
	 * @return <code>true</code> if the class is assignable to the class name,
	 *         <code>false</code> otherwise.
	 */
	private static boolean isAssignableToNoCache(Class clazz, String className) {
// mgoyal: This approach isn't safe to use as it can cause incorrect
// plugin load. Documenting this approach for further analysis. Don't
// remove or uncomment this.
//		try {
//			if(clazz.getName().equals(className))
//				return true;
//			
//			ClassLoader clsLoader = clazz.getClassLoader();
//			if(clsLoader != null) {
//				Class testCls = clsLoader.loadClass(className);
//				if(testCls != null && testCls.isAssignableFrom(clazz))
//					return true;
//			}
//			return false;
//		} catch (ClassNotFoundException e) {
//			return false;
//		}
//		
		
		// test the class itself
		if (clazz.getName().equals(className))
			return true;
		
		// test all the interfaces the class implements
		Class[] interfaces = clazz.getInterfaces();
		for (int i = 0; i < interfaces.length; i++) {
			if (checkInterfaceHierarchy(interfaces[i], className))
				return true;
		}
		
		// test superclass
		return isAssignableTo(clazz.getSuperclass(), className);
	}

	/**
	 * A map of classes that have been successfully loaded, keyed on the class
	 * name optionally prepended by the plugin ID, if specified.
	 */
	private static Map successLookupTable = new HashMap();
	
	/**
	 * A map of classes that could not be loaded, keyed on the class name
	 * optionally prepended by the plugin ID, if specified.
	 */
	private static Set failureLookupTable = new HashSet();

	/**
	 * Gets an adapter for <code>object</code> to the class described by
	 * <code>className</code> qualified by the optional <code>pluginId</code>.
	 * 
	 * @param object
	 *            the object to be adapted
	 * @param className
	 *            the name of the adapter class
	 * @param pluginId
	 *            the optional plugin ID (can be <code>null/code>)
	 * @return the adapted object, or <code>null</code> if it couldn't be found
	 */
	protected static Object getAdapter(Object object, String className, String pluginId) {
		if (!(object instanceof IAdaptable))
			return null;
		if(pluginId != null) {
			Class theClass = loadClass(className,pluginId);
			return theClass != null ? ((IAdaptable) object).getAdapter(theClass) : null;
		}
		return null;
	}

	/**
	 * A utility method to invoke a cascading list of methods.
	 * 
	 * @param methodDescriptor
	 *            the first method descriptor
	 * @param object
	 *            The object to invoke the method on
	 * @return the value of the invokation
	 */
	protected static Object invokeMethod(MethodDescriptor methodDescriptor, Object object) {
		String methodSignature = null;
		Class clazz =null;
		try {
			if (methodDescriptor == null || object == null)
				return null;
            if (!methodDescriptor.isInitialized()){
                methodDescriptor.initialize();
            }
			methodSignature = methodDescriptor.getSignature();
			clazz = object.getClass();
			if (passiveClasses.contains(clazz,methodSignature))
				return null;
			Method method = classToMethodSignatureToMethodCach.
				getMethod(clazz,methodSignature);
			if(method==null){
				method = clazz.getMethod(methodDescriptor.getName(),
										 methodDescriptor.getParameterTypes());
				classToMethodSignatureToMethodCach.addMethod(clazz,methodSignature,method);
			}
			Object valueObj = 
				method.invoke(object, methodDescriptor.getParameters());
			if (methodDescriptor.getNext() == null)
				return valueObj == null ? NULL : valueObj;
			return invokeMethod(methodDescriptor.getNext(), valueObj);
		} catch (Exception e) {
			passiveClasses.addMethod(clazz,methodSignature);
			return null;
		}
	}
	
	/**
	 * A utility method to invoke a cascading list of methods.
	 * 
	 * @param StaticMethodDescriptor
	 *            the static method descriptor
	 * @param object
	 *            The context object to use (it could be null)
	 * @return the value of the invokation
	 */
	protected static Object invokeStaticMethod(StaticMethodDescriptor methodDescriptor, Object object) {
		try {
			if (methodDescriptor == null)
				return null;
            if (!methodDescriptor.isInitialized()){
                methodDescriptor.initialize();
            }
			
			Object[] valuesCopy = null;
            if (methodDescriptor.getParameters() != null) {
                valuesCopy = methodDescriptor.getParameters()
                    .clone();
                for (int i = 0; i < valuesCopy.length; i++) {
                    if (valuesCopy[i].equals(contextParam)) {
                        valuesCopy[i] = object;
                    }
                }
            }
			
			Method method = getStaticMethod(methodDescriptor);
			Object valueObj = (method != null) ? method.invoke(object,
                valuesCopy)
                : null;

			if (methodDescriptor.getNext() == null)
				return valueObj == null ? NULL : valueObj;
			return invokeMethod(methodDescriptor.getNext(), valueObj);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * utility method used to get a static method object
	 * @param pluginID			the plugin that owns the class
	 * @param className			the class to use to call hte static method
	 * @param methodName		the method to get
	 * @param ParameterTypes	the parameter types 
	 * @return					the  method object
	 */
	private static Method getStaticMethod(StaticMethodDescriptor staticMethodDescriptor) {
		Class theClass = loadClass(staticMethodDescriptor.getClassName(),
									staticMethodDescriptor.getPluginID());
		if (theClass==null)
			return null;
		Method theMethod = null;
		try {
			String methodSignature = staticMethodDescriptor.getSignature(); 
			theMethod = classToMethodSignatureToMethodCach.getMethod(theClass,methodSignature);
			if(theMethod==null){
			   theMethod = theClass.getMethod(staticMethodDescriptor.getName(),
											staticMethodDescriptor.getParameterTypes());
				classToMethodSignatureToMethodCach.addMethod(theClass,methodSignature,theMethod);
			}
		} catch (SecurityException e) {
			// no special handling needed;
		} catch (NoSuchMethodException e) {
			// no special handling needed;
		}
		return theMethod;
	}

	/**
	 * Check the interfaces the whole way up. If one of them matches
	 * <code>className</code> return <code>true</code>. Optimized to look
	 * first in a cache of previously retrieved results.
	 * 
	 * @param interfaceToCheck
	 *            The interface whose name we are testing.
	 * @param className
	 *            the name of the interface to we are trying to match
	 * @return <code>true</code> if one of the interfaces in the hierarchy
	 *         matches <code>className</code>,<code>false</code>
	 *         otherwise.
	 */
	private static boolean checkInterfaceHierarchy(Class interfaceToCheck, String className) {
		
		if ( contains(isNotAssignableTable, interfaceToCheck, className) ) {
			return false;
		}
		
		if ( contains(isAssignableTable, interfaceToCheck, className) ) {
			return true;
		}
		
		boolean result = checkInterfaceHierarchyNoCache(interfaceToCheck,className);
		
		if (result) {
			add(isAssignableTable, interfaceToCheck, className);
		} else {
			add(isNotAssignableTable, interfaceToCheck, className);
		}
		
		return result;
	}

	/**
	 * Check the interfaces the whole way up. If one of them matches
	 * <code>className</code> return <code>true</code>.
	 * 
	 * @param interfaceToCheck
	 *            The interface whose name we are testing.
	 * @param className
	 *            the name of the interface to we are trying to match
	 * @return <code>true</code> if one of the interfaces in the hierarchy
	 *         matches <code>className</code>,<code>false</code>
	 *         otherwise.
	 */
	private static boolean checkInterfaceHierarchyNoCache(Class interfaceToCheck, String className) {
		if(interfaceToCheck.getName().equals(className))
			return true;
		Class[] superInterfaces = interfaceToCheck.getInterfaces();
		for (int i = 0; i < superInterfaces.length; i++) {
			if(checkInterfaceHierarchy(superInterfaces[i], className))
				return true;
		}
		return false;
	}
	
	/**
	 * Determines whether the <code>map</code> contains an entry for the
	 * <key,value>pair.
	 * 
	 * @param map
	 *            the map in which to find the key and value
	 * @param key
	 *            the key
	 * @param value
	 *            the value
	 * @return <code>true</code> if the map contains the key/value pair,
	 *         <code>false</code> otherwise
	 */
	private static boolean contains(Map map, Object key, String value) {
		
		boolean result = false;
		
		Object val = map.get(key);
		if (val != null) {
			Set values = (Set)val;
			result = values.contains(value);
		}
		
		return result;
	}
	
	/**
	 * Adds the <key,value>pair to the <code>map</code>.
	 * 
	 * @param map
	 *            the map in which to add the value
	 * @param key
	 *            the key
	 * @param value
	 *            the value
	 */
	private static void add(Map map, Object key, String value) {
		
		Set values = (Set)map.get(key);
		if (values == null) {
			values = new HashSet();
			map.put(key, values);
		}
		
		values.add(value);
	}
}
