package org.parallelj.launching.internal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.ServiceLoader;

import org.parallelj.launching.Launch;

public class LaunchingObservable {

	private static class LaunchingListenerComparator implements Comparator<LaunchingListener> {

	    @Override
	    public int compare(LaunchingListener o1, LaunchingListener o2) {
	    	if(o1.getPriority()>o2.getPriority())
	    		return -1;
	    	else if(o1.getPriority()<o2.getPriority())
	    		return +1;
	    	else
	    		return 0;
	    }
    }           

	
	private static final ServiceLoader<LaunchingListener> loader = ServiceLoader.load(LaunchingListener.class);
	private static final List<Class<? extends LaunchingListener>> listenersClasses = new ArrayList<Class<? extends LaunchingListener>>();

	static {
		List<LaunchingListener> lst = new ArrayList<LaunchingListener>();
		// load built-in listener from META-INF
		for (LaunchingListener listener : loader) {
			lst.add(listener);
		}
		
		Collections.sort(lst, new LaunchingListenerComparator());
		for (LaunchingListener launchingListener : lst) {
			listenersClasses.add(launchingListener.getClass()); 
		}
	}
	
	private List<LaunchingListener> listeners = new ArrayList<LaunchingListener>();
	
	public LaunchingObservable() {
		for (Class<? extends LaunchingListener> listenerClass : listenersClasses) {
			try {
				listeners.add(listenerClass.newInstance());
			} catch (Exception e) {
				// TODO: add message kind
				e.printStackTrace();
			}
		}
	}
	
	public void prepareLaunching(Launch<?> launch) {
		for (LaunchingListener listener : this.listeners) {
			try {
				listener.prepareLaunching(launch);
			} catch (Exception e) {
				// TODO: add message kind
				e.printStackTrace();
			}
		}
	}
	
	public void finalizeLaunching(Launch<?> launch) {
		for (LaunchingListener listener : this.listeners) {
			try {
				listener.finalizeLaunching(launch);
			} catch (Exception e) {
				// TODO: add message kind
				e.printStackTrace();
			}
		}
	}
	
}

@@ -255,16 +255,132 @@
 able %7B%0A%0A
+%09private static class Holder %7B%0A%09%09private static final LaunchingObservable INSTANCE = new LaunchingObservable();%0A%09%7D%0A%0A
 %09private
@@ -723,44 +723,279 @@
    %7D
-           %0A%0A%09%0A%09private static final
+%0A%09%0A%09public static final LaunchingObservable getInstance() %7B%0A%09%09return Holder.INSTANCE;%0A%09%7D%0A%0A%09private ServiceLoader%3CLaunchingListener%3E loader;%0A%09private List%3CLaunchingListener%3E listeners = new ArrayList%3CLaunchingListener%3E();%0A%09%0A%09private LaunchingObservable() %7B%0A%09%09this.loader =
  Ser
@@ -996,33 +996,38 @@
  = ServiceLoader
-%3C
+.load(
 LaunchingListene
@@ -1031,86 +1031,500 @@
 ener
-%3E loader = ServiceLoader.load(LaunchingListener.class);%0A%09private static final 
+.class, LaunchingObservable.class.getClassLoader());%0A%09%09System.out.println(this.loader.iterator().hasNext());%0A%09%09if (this.loader==null %7C%7C this.loader.iterator()==null %7C%7C !this.loader.iterator().hasNext()) %7B%0A%09%09%09this.loader = ServiceLoader.load(LaunchingListener.class, Thread.currentThread().getContextClassLoader());%0A%09%09%7D%0A%09%09if (this.loader==null %7C%7C this.loader.iterator()==null %7C%7C !this.loader.iterator().hasNext()) %7B%0A%09%09%09this.loader = ServiceLoader.loadInstalled(LaunchingListener.class);%0A%09%09%7D%0A%09%09
 List
@@ -1559,16 +1559,17 @@
 stener%3E%3E
+ 
  listene
@@ -1637,18 +1637,10 @@
 ();%0A
-%0A%09static %7B
+%09%09
 %0A%09%09L
@@ -1997,127 +1997,8 @@
 %09%09%7D%0A
-%09%7D%0A%09%0A%09private List%3CLaunchingListener%3E listeners = new ArrayList%3CLaunchingListener%3E();%0A%09%0A%09public LaunchingObservable() %7B
 %0A%09%09f
@@ -2077,32 +2077,37 @@
  %7B%0A%09%09%09try %7B%0A%09%09%09%09
+this.
 listeners.add(li
@@ -2234,24 +2234,37 @@
 %7D%0A%09%0A%09public 
+synchronized 
 void prepare
@@ -2499,16 +2499,29 @@
 %09public 
+synchronized 
 void fin

Define LaunchingObservable as a singleton