public static void init(final Unmarshaller unmarshaller) {
		if(plugins == null) {
			plugins = new HashMap<String, Plugin>();
			pluginClassloaders = new HashMap<String, ClassLoader>();
			pluginMethods = new HashMap<String, Method>();
					
			File pluginsDir = new File("plugins");
			if(pluginsDir != null && pluginsDir.exists() && pluginsDir.isDirectory()) {
				System.out.println("Plugins directory found.");
				File[] pluginFolders = pluginsDir.listFiles();
				if (pluginFolders != null) {
					for (final File pluginFolder : pluginFolders) {
						if (pluginFolder != null && pluginFolder.exists() && pluginFolder.isDirectory()) {
							File crtPlugin = new File(pluginFolder, "plugin.xml");
							if (crtPlugin != null && crtPlugin.exists() && crtPlugin.isFile()) {
								System.out.println("Reading: " + crtPlugin.getAbsolutePath());
								try {
									Object pluginObject = unmarshaller.unmarshal(crtPlugin);
									if (pluginObject instanceof Plugin) {
										Plugin plugin = (Plugin) pluginObject;
										String pluginName = pluginFolder.getName();
										if (plugin.getName() != null) {
											pluginName = plugin.getName();
										}
										
										// Detect duplicate plugin
										if(plugins.get(pluginName) != null) {
											throw new AzotException("A plugin named '" + pluginName + "' has already be loaded.");
										}

										List<URL> urls = new ArrayList<URL>();
										File[] pluginContentFiles = pluginFolder.listFiles();
										for (File pluginContentFile : pluginContentFiles) {
											urls.add(pluginContentFile.toURI().toURL());
										}
										
										URLClassLoader pluginClassloader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
										
										Class<?> pluginClass = pluginClassloader.loadClass(plugin.getClazz());
										
										final Method pluginMethod = pluginClass.getDeclaredMethod("execute", Properties.class);
										if (!Properties.class.equals(pluginMethod.getReturnType())) {
											throw new AzotException("The return type of the execute() method must be 'java.util.Properties' (not '" + pluginMethod.getReturnType().getName() + "')");
										}
										
										if (!Modifier.isStatic(pluginMethod.getModifiers()) || !Modifier.isPublic(pluginMethod.getModifiers())) {
											throw new AzotException("The execute() method must be declared 'public' and 'static'");
										}
										
										
										plugins.put(pluginName, plugin);
										pluginClassloaders.put(pluginName, pluginClassloader);
										pluginMethods.put(pluginName, pluginMethod);
										System.out.println("Success: plugin '" + pluginName + "' added.");
									}
								} catch (Exception e) {
									println("Error: unable to load plugin");
									if (AzotConfig.GLOBAL.VERBOSE) {
										System.out.print("Cause: ");
										e.printStackTrace();
									}
								}
							}
						}
					}
				}
			}
		}
	}