import java.io.BufferedReader;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 *
 */
public class Platform {

    private static Platform instance;
    private static Map<String, Object> extensions;
    private static Set<Description> descriptions;

    private Platform() {}

    public Object loadExtension(Description description) throws Exception {
        if (extensions == null)
            extensions = new HashMap<String, Object>();
        else if (extensions.containsKey(description.getName())) {
            return extensions.get(description.getName());
        }

        Class<?> afficheurClass = Class.forName(description.getName());
        Object extension = afficheurClass.newInstance();

        return extension;
    }

    public static Set<Description> getDescriptions() throws Exception {
        if(descriptions == null) {
            descriptions = new HashSet<Description>();

            BufferedReader br = new BufferedReader(new FileReader("afficheur.txt"));

            String line;
            Description description = new Description();
            while ((line = br.readLine()) != null) {
                if (line.isEmpty()) {
                    if (description.getName() != null) {
                        descriptions.add(description);
                    }

                    description = new Description();
                }

                String split[] = line.split(" = ");
                String key = split[0];
                String value = split[1];

                for (Method m : Description.class.getMethods()) {
                    if (m.getName().equals("set" + key)) {
                        Class<?> parameterType = m.getParameterTypes()[0];
                        if (parameterType.equals(String.class)) {
                            m.invoke(description, value);
                        } else if (parameterType.equals(Boolean.class)) {
                            m.invoke(description, Boolean.parseBoolean(value));
                        } else {
                            throw new Exception("unknown parameter type: " + parameterType.getName());
                        }

                        break;
                    }
                }
            }
        }

        return descriptions;
    }

    public static Platform getInstance() {
        if (instance == null)
            instance = new Platform();

        return instance;
    }
}

@@ -84,16 +84,101 @@
 Method;%0A
+import java.lang.reflect.Proxy;%0Aimport java.net.URL;%0Aimport java.net.URLClassLoader;%0A
 import j
@@ -359,30 +359,35 @@
  static Map%3C
-String
+Description
 , Object%3E ex
@@ -445,16 +445,60 @@
 iptions;
+%0A    private static ClassLoader classLoader;
 %0A%0A    pr
@@ -515,16 +515,21 @@
 form() %7B
+%0A    
 %7D%0A%0A    p
@@ -668,22 +668,27 @@
 HashMap%3C
-String
+Description
 , Object
@@ -743,26 +743,16 @@
 cription
-.getName()
 )) %7B%0A   
@@ -789,34 +789,189 @@
 (description
-.getName()
+);%0A        %7D%0A%0A        if(classLoader == null) %7B%0A            URL url = new URL(%22.%22);%0A            URL urls%5B%5D = %7Burl%7D;%0A            classLoader = new URLClassLoader(urls
 );%0A        %7D
@@ -989,25 +989,25 @@
 lass%3C?%3E 
-afficheur
+extension
 Class = 
@@ -1033,35 +1033,55 @@
 iption.getName()
+, true, classLoader
 );%0A
+%0A
         Object e
@@ -1092,20 +1092,260 @@
 sion
- = afficheur
+;%0A        if (description.isProxy()) %7B%0A            Class%3C?%3E%5B%5D interfaces = %7BextensionClass%7D;%0A%0A            extension = Proxy.newProxyInstance(classLoader, interfaces, null /*new ProxyHandler(target)*/);%0A        %7D else %7B%0A            extension = extension
 Clas
@@ -1360,16 +1360,26 @@
 tance();
+%0A        %7D
 %0A%0A      
@@ -1487,16 +1487,17 @@
       if
+ 
 (descrip

add Proxy/ClassLoader