Bug 304584 -  [Tooling] Implement Workbench-Model-Tooling
* align with changes in bug 284357
diff --git a/bundles/org.eclipse.e4.tools.compat/src/org/eclipse/e4/tools/compat/internal/ReflectionContributionFactory.java b/bundles/org.eclipse.e4.tools.compat/src/org/eclipse/e4/tools/compat/internal/ReflectionContributionFactory.java
index 9e4ed7f..6dca4ee 100644
--- a/bundles/org.eclipse.e4.tools.compat/src/org/eclipse/e4/tools/compat/internal/ReflectionContributionFactory.java
+++ b/bundles/org.eclipse.e4.tools.compat/src/org/eclipse/e4/tools/compat/internal/ReflectionContributionFactory.java
@@ -1,12 +1,6 @@
 package org.eclipse.e4.tools.compat.internal;
 
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 import javax.inject.Inject;
@@ -30,158 +24,76 @@
 /**
  * Create the contribution factory.
  */
+@SuppressWarnings("restriction")
 public class ReflectionContributionFactory implements IContributionFactory {
 
 	private IExtensionRegistry registry;
 	private Map<String, Object> languages;
-	
+
 	@Inject
 	private PackageAdmin packageAdmin;
 	
 	@Inject
 	private Logger logger;
-
+	
 	/**
 	 * Create a reflection factory.
 	 * 
 	 * @param registry
 	 *            to read languages.
 	 */
-	@Inject
 	public ReflectionContributionFactory(IExtensionRegistry registry) {
 		this.registry = registry;
 		processLanguages();
 	}
 
-	public Object call(Object object, String uriString, String methodName, IEclipseContext context,
-			Object defaultValue) {
-		if (uriString != null) {
-			URI uri = new URI(uriString);
-			if (uri.segments.length > 3) {
-				String prefix = uri.segments[2];
-				IContributionFactorySpi factory = (IContributionFactorySpi) languages.get(prefix);
-				return factory.call(object, methodName, context, defaultValue);
-			}
-		}
-
-		Method targetMethod = null;
-
-		Method[] methods = object.getClass().getMethods();
-
-		// Optimization: if there's only one method, use it.
-		if (methods.length == 1) {
-			targetMethod = methods[0];
-		} else {
-			ArrayList<Method> toSort = new ArrayList<Method>();
-
-			for (int i = 0; i < methods.length; i++) {
-				Method method = methods[i];
-
-				// Filter out non-public constructors
-				if ((method.getModifiers() & Modifier.PUBLIC) != 0
-						&& method.getName().equals(methodName)) {
-					toSort.add(method);
-				}
-			}
-
-			// Sort the methods by descending number of method
-			// arguments
-			Collections.sort(toSort, new Comparator<Method>() {
-				/*
-				 * (non-Javadoc)
-				 * 
-				 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
-				 */
-				public int compare(Method m1, Method m2) {
-					int l1 = m1.getParameterTypes().length;
-					int l2 = m2.getParameterTypes().length;
-
-					return l1 - l2;
-				}
-			});
-
-			// Find the first satisfiable method
-			for (Iterator<Method> iter = toSort.iterator(); iter.hasNext() && targetMethod == null;) {
-				Method next = iter.next();
-
-				boolean satisfiable = true;
-
-				Class<?>[] params = next.getParameterTypes();
-				for (int i = 0; i < params.length && satisfiable; i++) {
-					Class<?> clazz = params[i];
-
-					if (!context.containsKey(clazz.getName())
-							&& !IEclipseContext.class.equals(clazz)) {
-						satisfiable = false;
-					}
-				}
-
-				if (satisfiable) {
-					targetMethod = next;
-				}
-			}
-		}
-
-		if (targetMethod == null) {
-			if (defaultValue != null) {
-				return defaultValue;
-			}
-			throw new RuntimeException(
-					"could not find satisfiable method " + methodName + " in class " + object.getClass()); //$NON-NLS-1$//$NON-NLS-2$
-		}
-
-		Class<?>[] paramKeys = targetMethod.getParameterTypes();
-
-		try {
-			logger.debug("calling: " + methodName);
-			Object[] params = new Object[paramKeys.length];
-			for (int i = 0; i < params.length; i++) {
-				if (IEclipseContext.class.equals(paramKeys[i])) {
-					params[i] = context;
-				} else {
-					params[i] = context.get(paramKeys[i].getName());
-				}
-			}
-
-			return targetMethod.invoke(object, params);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw new RuntimeException(e);
-		}
+	public Object create(String uriString, IEclipseContext context, IEclipseContext staticContext) {
+		return doCreate(uriString, context, staticContext);
 	}
 
 	public Object create(String uriString, IEclipseContext context) {
+		return doCreate(uriString, context, null);
+	}
+
+	private Object doCreate(String uriString, IEclipseContext context, IEclipseContext staticContext) {
 		if (uriString == null) {
 			return null;
 		}
-		URI uri = new URI(uriString);
+		URI uri = URI.createURI(uriString);
 		Bundle bundle = getBundle(uri);
 		Object contribution;
 		if (bundle != null) {
-			contribution = createFromBundle(bundle, context, uri);
+			contribution = createFromBundle(bundle, context, staticContext, uri);
 		} else {
 			contribution = null;
-			logger.error("Unable to retrive the bundle from the URI: "+ uriString);
+			logger.error("Unable to retrive the bundle from the URI: " //$NON-NLS-1$
+					+ uriString);
 		}
 		return contribution;
 	}
 
-	protected Object createFromBundle(Bundle bundle, IEclipseContext context, URI uri) {
+	protected Object createFromBundle(Bundle bundle, IEclipseContext context,
+			IEclipseContext staticContext, URI uri) {
 		Object contribution;
-		if (uri.segments.length > 3) {
-			String prefix = uri.segments[2];
+		if (uri.segmentCount() > 3) {
+			String prefix = uri.segment(2);
 			IContributionFactorySpi factory = (IContributionFactorySpi) languages.get(prefix);
-			StringBuffer resource = new StringBuffer(uri.segments[3]);
-			for (int i = 4; i < uri.segments.length; i++) {
+			StringBuffer resource = new StringBuffer(uri.segment(3));
+			for (int i = 4; i < uri.segmentCount(); i++) {
 				resource.append('/');
-				resource.append(uri.segments[i]);
+				resource.append(uri.segment(i));
 			}
 			contribution = factory.create(bundle, resource.toString(), context);
 		} else {
-			String clazz = uri.segments[2];
+			String clazz = uri.segment(2);
 			try {
 				Class<?> targetClass = bundle.loadClass(clazz);
-				contribution = ContextInjectionFactory.make(targetClass, context);
+				if (staticContext == null)
+					contribution = ContextInjectionFactory.make(targetClass, context);
+				else
+					contribution = ContextInjectionFactory
+							.make(targetClass, context, staticContext);
+
 				if (contribution == null) {
 					String message = "Unable to load class '" + clazz + "' from bundle '" //$NON-NLS-1$ //$NON-NLS-2$
 							+ bundle.getBundleId() + "'"; //$NON-NLS-1$
@@ -191,12 +103,12 @@
 				contribution = null;
 				String message = "Unable to load class '" + clazz + "' from bundle '" //$NON-NLS-1$ //$NON-NLS-2$
 						+ bundle.getBundleId() + "'"; //$NON-NLS-1$
-				logger.error(message);
+				logger.error(e,message);
 			} catch (InjectionException e) {
 				contribution = null;
 				String message = "Unable to create class '" + clazz + "' from bundle '" //$NON-NLS-1$ //$NON-NLS-2$
 						+ bundle.getBundleId() + "'"; //$NON-NLS-1$
-				logger.error(message);
+				logger.error(e, message);
 			}
 		}
 		return contribution;
@@ -221,6 +133,7 @@
 		}
 	}
 
+
 	protected Bundle getBundle(URI platformURI) {
 		return getBundleForName(platformURI.segments[1]);
 	}
@@ -248,19 +161,25 @@
 		}
 		return null;
 	}
-
+	
 	static class URI {
 		String[] segments;
 		String uri;
 		
-		private URI(String uriString) {
+		URI(String uriString) {
 			segments = uriString.substring(uriString.indexOf('/')+1).split("/");
 		}
-	}
+		
+		public String segment(int i) {
+			return segments[i];
+		}
 
-	public Object create(String uriString, IEclipseContext context,
-			IEclipseContext staticContext) {
-		// TODO Auto-generated method stub
-		return null;
+		public int segmentCount() {
+			return segments.length;
+		}
+
+		static URI createURI(String uriString) {
+			return new URI(uriString);
+		}
 	}
 }