diff --git a/CHANGES.txt b/CHANGES.txt
index 3b1c4a43d1489a7e29cfc57f784a538ec9b45341..14894785e32a8834ce9888f5db6f640e96f802ed 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,10 +1,15 @@
 Changes
 =======
 
-0.39 (unreleased)
+0.40 (Unreleased)
 -----------------
 
- * No changes yet.
+ * seleniumrunner initial release. [Cedric de Saint Martin]
+ 
+0.39 (2012-02-20)
+-----------------
+
+ * seleniumrunner initial release. [Cedric de Saint Martin]
 
 0.38 (2011-12-05)
 -----------------
diff --git a/component/alsa/buildout.cfg b/component/alsa/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..3c91b1fdfd3e392dc589c33b54bf42eaad54cf81
--- /dev/null
+++ b/component/alsa/buildout.cfg
@@ -0,0 +1,21 @@
+[buildout]
+parts =
+  alsa
+
+[alsa]
+# Contains libasound
+recipe = hexagonit.recipe.cmmi
+url = ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.24.1.tar.bz2
+#md5sum = d55a9d7d2a79d738a1b7a511cffda4b6
+configure-options =
+  --disable-static
+  --disable-aload
+  --disable-mixer
+  --disable-pcm
+  --disable-rawmidi
+  --disable-hwdep
+  --disable-seq
+  --disable-ucm
+  --disable-alisp
+  --disable-old-symbols
+  --disable-python
\ No newline at end of file
diff --git a/component/chromium/buildout.cfg b/component/chromium/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..c7fcc4735f7410e5011b79075cc24fc1df07a4de
--- /dev/null
+++ b/component/chromium/buildout.cfg
@@ -0,0 +1,47 @@
+[buildout]
+extends =
+  ../dbus/buildout.cfg
+  ../fontconfig/buildout.cfg
+  ../glib/buildout.cfg
+  ../gtk-2/buildout.cfg
+  ../libpng/buildout.cfg
+  ../xorg/buildout.cfg
+
+parts = 
+  chromium
+  
+[chromium]
+recipe = slapos.recipe.build
+slapos_promise =
+  file:chrome
+  file:chrome-wrapper
+  file:chrome-slapos
+
+#chromium zip files for linux seem to be corrupted : rights are not correctly
+#set (+x) when unzipping using python, but it works when doing "unzip chromium.zip"
+#AND it works when unzipping any other archive with python.
+#Conclusion : Google, please, learn how to make zip files.
+linux_x86 = http://commondatastorage.googleapis.com/chromium-browser-continuous/Linux/109696/chrome-linux.zip 8ba6c022849b2a882b6e65163c147eb9
+linux_x86-64 = http://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/109696/chrome-linux.zip a3ed3feb285ecfe7c722576db80d5099
+mac_x86-64 = http://commondatastorage.googleapis.com/chromium-browser-continuous/Mac/100142/chrome-mac.zip cb3a76b8a1a93be94df2f500fb621131
+
+script =
+  #If part directory already exist, will just throw an error.
+  import sys
+  platform = '%%s_%%s' %% (guessOperatingSystem(), guessPlatform())
+  if not self.options.get('url'): self.options['url'], self.options['md5sum'] = self.options[platform].split(' ')
+  extract_dir = self.extract(self.download(self.options['url'], self.options.get('md5sum')))
+  workdir = guessworkdir(extract_dir)
+  self.copyTree(workdir, "%(location)s")
+  wrapper_location = os.path.join("%(location)s", "chrome-slapos")
+  wrapper = open(wrapper_location, 'w')
+  wrapper.write("""#!/bin/sh
+  export LD_LIBRARY_PATH=${libXrender:location}/lib/:${fontconfig:location}/lib/:${dbus:location}/lib/:${dbus-glib:location}/lib/:${pango:location}/lib:${cairo:location}/lib:${glib:location}/lib:${gtk-2:location}/lib:${atk:location}/lib:${gdk-pixbuf:location}/lib:${libXt:location}/lib:${gtk-2:location}/lib:${libpng:location}/lib:%(location)s
+  %(location)s/chrome""")
+  wrapper.flush()
+  wrapper.close()
+  os.chmod(wrapper_location, 0766)
+  os.chmod(os.path.join("%(location)s", 'chrome'), 0766)
+  os.chmod(os.path.join("%(location)s", 'chrome-wrapper'), 0766)
+
+# requirements : libXrender1 libxss1 x11-common
\ No newline at end of file
diff --git a/component/dbus/buildout.cfg b/component/dbus/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..d51359506dc6700103a840597942d8f30e1c9676
--- /dev/null
+++ b/component/dbus/buildout.cfg
@@ -0,0 +1,30 @@
+[buildout]
+extends =
+  ../libxml2/buildout.cfg
+  ../pkgconfig/buildout.cfg
+  ../libexpat/buildout.cfg
+
+parts =
+  dbus
+
+[dbus]
+recipe = hexagonit.recipe.cmmi
+url = http://dbus.freedesktop.org/releases/dbus/dbus-1.4.10.tar.gz
+md5sum = 402a2f8102bedbe236e2891b2b0f31c2
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${libxml2:location}/lib/pkgconfig
+  CPPFLAGS=-I${libexpat:location}/include
+  LDFLAGS=-L${libexpat:location}/lib
+
+[dbus-glib]
+recipe = hexagonit.recipe.cmmi
+url = http://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-0.94.tar.gz
+md5sum = e1f1506a6f4941e67bffd614b1ad5af6
+environment =
+  PATH=${pkgconfig:location}/bin:${glib:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${dbus:location}/lib/pkgconfig:${glib:location}/lib/pkgconfig
+  CPPFLAGS=-I${libexpat:location}/include
+  LDFLAGS=-L${libexpat:location}/lib -L${gettext:location}/lib
diff --git a/component/firefox/buildout.cfg b/component/firefox/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..4b8bf8a4d5d48b1144835ecc1d9124c81cc813b1
--- /dev/null
+++ b/component/firefox/buildout.cfg
@@ -0,0 +1,40 @@
+[buildout]
+extends =
+  ../alsa/buildout.cfg
+  ../xorg/buildout.cfg
+  ../fontconfig/buildout.cfg
+  ../dbus/buildout.cfg
+  ../gtk-2/buildout.cfg
+  ../libpng/buildout.cfg
+
+parts =
+  firefox
+
+[firefox]
+recipe = slapos.recipe.build
+slapos_promise =
+  file:firefox
+  file:firefox-bin
+
+depends =
+  ${liberation-fonts:location}
+  ${ipaex-fonts:location}
+
+x86 = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/7.0.1/linux-i686/fr/firefox-7.0.1.tar.bz2 42c2559892f26ed2a0563faaf693a00f
+x86-64 = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/7.0.1/linux-x86_64/en-US/firefox-7.0.1.tar.bz2 20d6c8e3dfc97d08d1dec7d0479f924f
+
+script =
+  if not self.options.get('url'): self.options['url'], self.options['md5sum'] = self.options[guessPlatform()].split(' ')
+  extract_dir = self.extract(self.download(self.options['url'], self.options.get('md5sum')))
+  workdir = guessworkdir(extract_dir)
+  self.copyTree(workdir, "%(location)s")
+  wrapper_location = os.path.join("%(location)s", "firefox-slapos")
+  wrapper = open(wrapper_location, 'w')
+  wrapper.write("""#!/bin/sh
+  cd %(location)s
+  export LD_LIBRARY_PATH=${libXrender:location}/lib/:${fontconfig:location}/lib/:${dbus:location}/lib/:${dbus-glib:location}/lib/:${pango:location}/lib:${cairo:location}/lib:${glib:location}/lib:${gtk-2:location}/lib:${atk:location}/lib:${gdk-pixbuf:location}/lib:${libXt:location}/lib:${libpng:location}/lib:${libSM:location}/lib:${libICE:location}/lib:${alsa:location}/lib:%(location)s
+  export PATH=${fontconfig:location}/bin:$PATH
+  %(location)s/firefox $*""")
+  wrapper.close()
+  os.chmod(wrapper_location, 0777)
+
diff --git a/component/fontconfig/buildout.cfg b/component/fontconfig/buildout.cfg
index 27081e36dad1f4c850c5a674428388763f0e429c..1198708d99db24b93ef9452bd5ec6770a3e9d29d 100644
--- a/component/fontconfig/buildout.cfg
+++ b/component/fontconfig/buildout.cfg
@@ -13,6 +13,7 @@ parts =
 recipe = hexagonit.recipe.cmmi
 url = http://fontconfig.org/release/fontconfig-2.8.0.tar.gz
 md5sum = 77e15a92006ddc2adbb06f840d591c0e
+# XXX-Cedric : should we use --with-add-fonts={somefont:location}/share,{someotherfont:location}/share?
 configure-options =
   --disable-static
   --disable-docs
diff --git a/component/gtk-2/buildout.cfg b/component/gtk-2/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..611f34efb7ce7f7283da2d9b8f9e2d9bb4172d27
--- /dev/null
+++ b/component/gtk-2/buildout.cfg
@@ -0,0 +1,82 @@
+[buildout]
+extends = 
+  ../glib/buildout.cfg
+  ../pkgconfig/buildout.cfg
+  ../libpng/buildout.cfg
+  ../xorg/buildout.cfg
+  ../zlib/buildout.cfg
+  ../freetype/buildout.cfg
+  ../fontconfig/buildout.cfg
+  ../gettext/buildout.cfg
+  ../libtiff/buildout.cfg
+  ../libjpeg/buildout.cfg
+    
+parts =
+  gtk-2
+
+[cairo]
+recipe = hexagonit.recipe.cmmi
+url = http://cairographics.org/releases/cairo-1.10.2.tar.gz
+md5sum = f101a9e88b783337b20b2e26dfd26d5f
+configure-options = 
+  --enable-tee=yes
+environment = 
+  PATH=${freetype:location}/bin:${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${zlib:location}/lib/pkgconfig:${libpng:location}/lib/pkgconfig:${pixman:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig
+  CPPFLAGS=-I${libpng:location}/include/ -I${zlib:location}/include -I${libX11:location}/include/ -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${render:location}/include
+  LDFLAGS=-L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${libXrender:location}/lib -Wl,-rpath=${libXrender:location}/lib
+  LD_LIBRARY_PATH=${render:location}/lib:${libX11:location}/lib:${libXrender:location}/lib
+
+[pango]
+recipe = hexagonit.recipe.cmmi
+url = http://ftp.gnome.org/pub/gnome/sources/pango/1.29/pango-1.29.3.tar.bz2
+md5sum = be4e3891353fae6b62a6f8d7689c4266
+configure-options = 
+  --disable-static
+# XXX-Cedric : Why, god, why do I have to supply the -lXrender option to linker?
+environment = 
+  PATH=${glib:location}/bin:${freetype:location}/bin:${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig:${fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${cairo:location}/lib/pkgconfig::${libXrender:location}/lib/pkgconfig
+  CPPFLAGS=-I${cairo:location}/include/cairo
+  LDFLAGS=-L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${libXrender:location}/lib -Wl,-rpath=${libXrender:location}/lib -lXrender
+  LD_LIBRARY_PATH=${render:location}/lib:${libX11:location}/lib:${libXrender:location}/lib
+
+[gdk-pixbuf]
+recipe = hexagonit.recipe.cmmi
+url = http://ftp.gnome.org/pub/gnome/sources/gdk-pixbuf/2.24/gdk-pixbuf-2.24.0.tar.bz2
+md5sum = d8ece3a4ade4a91c768328620e473ab8
+configure-options = 
+  --disable-static
+  --without-libintl-prefix
+environment = 
+  PATH=${glib:location}/bin:${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig:${gettext:location}/lib/pkgconfig:${fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${cairo:location}/lib/pkgconfig
+  CPPFLAGS=-I${libtiff:location}/include -I${libjpeg:location}/include -I${libpng:location}/include
+  LDFLAGS=-L${gettext:location}/lib -Wl,-rpath=${gettext:location}/lib -L${glib:location}/lib -Wl,-rpath=${glib:location}/lib -L${libtiff:location}/lib -Wl,-rpath=${libtiff:location}/lib -L${libjpeg:location}/lib -Wl,-rpath=${libjpeg:location}/lib -L${libpng:location}/lib -Wl,-rpath=${libpng:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
+  LD_LIBRARY_PATH=${glib:location}/lib:${gettext:location}/lib
+  
+[atk]
+recipe = hexagonit.recipe.cmmi
+url = http://ftp.gnome.org/pub/gnome/sources/atk/2.0/atk-2.0.1.tar.bz2
+md5sum = 87f20b78deaedef858ac54358c0786b1
+environment = 
+  PATH=${glib:location}/bin:${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig
+  LDFLAGS=-L${gettext:location}/lib -Wl,-rpath=${gettext:location}/lib -L${glib:location}/lib -Wl,-rpath=${gettext:location}/lib
+  LD_LIBRARY_PATH=${glib:location}/lib:${gettext:location}/lib
+
+[gtk-2]
+recipe = hexagonit.recipe.cmmi
+url = http://ftp.gnome.org/pub/gnome/sources/gtk+/2.24/gtk+-2.24.6.tar.bz2
+md5sum = 421100f6597e613234f8dead6091a9fe
+configure-options = 
+  --disable-static
+  --disable-cups
+  --disable-papi
+  --enable-explicit-deps
+environment = 
+  PATH=${gdk-pixbuf:location}/bin:${glib:location}/bin:${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${glib:location}/lib/pkgconfig:${gettext:location}/lib/pkgconfig:${fontconfig:location}/lib/pkgconfig:${freetype:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${cairo:location}/lib/pkgconfig:${atk:location}/lib/pkgconfig:${gdk-pixbuf:location}/lib/pkgconfig:${pango:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${pixman:location}/lib/pkgconfig:${libpng:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libXrender:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xcbproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig
+  CPPFLAGS=-I${libtiff:location}/include -I${libjpeg:location}/include -I${libpng:location}/include -I${libX11:location}/include/ -I${xproto:location}/include -I${kbproto:location}/include -I${libXrender:location}/include -I${render:location}/include -I${libXext:location}/include -I${cairo:location}/include/cairo
+  LDFLAGS=-L${gettext:location}/lib -L${glib:location}/lib -L${libtiff:location}/lib -L${libjpeg:location}/lib -L${libpng:location}/lib -L${zlib:location}/lib -L${libXrender:location}/lib -L${libX11:location}/lib -L${libXext:location}/lib -L${pango:location}/lib
+  LD_LIBRARY_PATH=${glib:location}/lib:${gettext:location}/lib:${libX11:location}/lib
diff --git a/component/intltool/buildout.cfg b/component/intltool/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..70835edcdba553e50ee09d17cf199cf162bf9cad
--- /dev/null
+++ b/component/intltool/buildout.cfg
@@ -0,0 +1,19 @@
+[buildout]
+extends =
+  ../gettext/buildout.cfg
+  ../perl/buildout.cfg
+  ../perl-XML-Parser/buildout.cfg
+
+parts = 
+  intltool
+
+[intltool]
+recipe = hexagonit.recipe.cmmi
+url = http://edge.launchpad.net/intltool/trunk/0.41.1/+download/intltool-0.41.1.tar.gz
+md5sum = d6c91bf06681919ccfdf3624035b75dc
+depends =
+  ${perl:version}
+  ${perl-XML-Parser:location}
+environment =
+  PATH=${perl:location}/bin:${gettext:location}/bin:${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${perl:location}/lib/pkgconfig
diff --git a/component/mesa/buildout.cfg b/component/mesa/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..5e04066cd24693ac1a4ef815a8b957902f0f9f1d
--- /dev/null
+++ b/component/mesa/buildout.cfg
@@ -0,0 +1,41 @@
+[buildout]
+extends = 
+  ../xorg/buildout.cfg
+
+parts = 
+  mesa
+
+[libdrm]
+#does not seem to compile with -jX
+recipe = hexagonit.recipe.cmmi
+url = http://dri.freedesktop.org/libdrm/libdrm-2.4.26.tar.bz2
+md5sum = 062569426773f69b11a47a7712bba770
+configure-options = 
+  --enable-nouveau-experimental-api
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${xorg-libpthread-stubs:location}/lib/pkgconfig:${pciaccess:location}/lib/pkgconfig
+
+
+[mesa]
+recipe = hexagonit.recipe.cmmi
+url = ftp://ftp.freedesktop.org//pub/mesa/7.11/MesaLib-7.11.tar.bz2
+md5sum = ff03aca82d0560009a076a87c888cf13
+configure-options = 
+  --disable-static
+  --disable-driglx-direct
+  --disable-glu
+  --disable-glw
+  --disable-glut
+  --disable-egl
+  --disable-gallium-llvm
+  --with-gallium-drivers=
+  --with-dri-drivers=
+  --with-expat=${libexpat:location}
+  --with-driver=xlib
+environment =
+  PATH=${pkgconfig:location}/bin:${makedepend:location}/bin:${flex:location}/bin:${bison:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${libdrm:location}/lib/pkgconfig:${dri2proto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${pciaccess:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${glproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libXext:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${xdamage:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig
+  CPPFLAGS=-I${libexpat:location}/include -I${libdrm:location}/include/libdrm -I${libdrm:location}/include -I${xproto:location}/include -I${libX11:location}/include -I${libXext:location}/include/ -I${xextproto:location}/include
+  LDFLAGS=-L${libexpat:location}/lib
+  PYTHON=${buildout:executable}
diff --git a/component/opera/buildout.cfg b/component/opera/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..01223165efa2427747387d53848c3a24af75d8a3
--- /dev/null
+++ b/component/opera/buildout.cfg
@@ -0,0 +1,47 @@
+[buildout]
+# Work in progress
+extends = 
+  ../xorg/buildout.cfg
+  ../fontconfig/buildout.cfg
+  ../dbus/buildout.cfg
+  ../gtk-2/buildout.cfg
+  ../libpng/buildout.cfg
+
+parts = 
+  opera
+  
+[opera]
+recipe = slapos.recipe.build
+slapos_promise =
+  file:opera
+
+depends = 
+  ${liberation-fonts:location}
+  ${ipaex-fonts:location}
+
+x86 = http://arc.opera.com/pub/opera/linux/1151/opera-11.51-1087.i386.linux.tar.bz2 91db21fc001e736a6432627fbf93062f
+x86-64 = todohttp://arc.opera.com/pub/opera/linux/1151/opera-11.51-1087.i386.linux.tar.bz2 91db21fc001e736a6432627fbf93062f
+
+script =
+  if not self.options.get('url'): self.options['url'], self.options['md5sum'] = self.options[guessPlatform()].split(' ')
+  extract_dir = self.extract(self.download(self.options['url'], self.options.get('md5sum')))
+  workdir = guessworkdir(extract_dir)
+  self.copyTree(workdir, "%(location)s")
+  wrapper_location = os.path.join("%(location)s", "opera-slapos")
+  wrapper = open(wrapper_location, 'w')
+  wrapper.write("""#!/bin/sh
+  cd %(location)s
+  export LD_LIBRARY_PATH=${libXrender:location}/lib/:${fontconfig:location}/lib/:${dbus:location}/lib/:${dbus-glib:location}/lib/:${pango:location}/lib:${cairo:location}/lib:${glib:location}/lib:${gtk-2:location}/lib:${atk:location}/lib:${gdk-pixbuf:location}/lib:${libXt:location}/lib:${libpng:location}/lib:${libSM:location}/lib:${libICE:location}/lib:%(location)s
+  export PATH=${fontconfig:location}/bin:$PATH
+  %(location)s/opera $*""")
+  wrapper.close()
+  profile_directory = os.path.join("%(location)s", "profile")
+  os.mkdir(profile_directory)
+  opera_config = open(os.path.join(profile_directory, "opera6.ini"), "w")
+  opera_config.write("""[State]
+  Reading Plugins=0
+  Accept License=1
+  Run=0""")
+  opera_config.close()
+  os.chmod(wrapper_location, 0766)
+
diff --git a/component/perl-XML-Parser/buildout.cfg b/component/perl-XML-Parser/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..b70813f62d065577b5c52dfb3ccdf8e5320a8296
--- /dev/null
+++ b/component/perl-XML-Parser/buildout.cfg
@@ -0,0 +1,30 @@
+[buildout]
+extends =
+  ../libexpat/buildout.cfg
+  ../libxml2/buildout.cfg
+  ../perl/buildout.cfg
+  ../perl-libwww-perl/buildout.cfg
+  ../zlib/buildout.cfg
+parts =
+  perl-XML-Parser
+
+[perl-XML-Parser]
+recipe = hexagonit.recipe.cmmi
+depends =
+  ${perl:version}
+  ${perl-libwww-perl:location}
+url = http://search.cpan.org/CPAN/authors/id/M/MS/MSERGEANT/XML-Parser-2.36.tar.gz
+md5sum = 1b868962b658bd87e1563ecd56498ded
+configure-command =
+  ${perl:location}/bin/perl Makefile.PL \
+    EXPATINCPATH=${libexpat:location}/include \
+    EXPATLIBPATH=${libexpat:location}/lib \
+    INC="-I${libxml2:location}/include/libxml2" \
+    LIBS="-L${libxml2:location}/lib -L${zlib:location}/lib"
+# Parallel make does not work for this package on fast machines
+# with many cores
+make-options =
+  OTHERLDFLAGS=" -Wl,-rpath=${libxml2:location}/lib -Wl,-rpath=${zlib:location}/lib" -j1
+environment =
+  LD_LIBRARY_PATH=${libxml2:location}/lib:${zlib:location}/lib
+  PERLLIB=blib/lib
diff --git a/component/qt/buildout.cfg b/component/qt/buildout.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..7806db1f11edf23e54c00a4a8f9018ddd36c6641
--- /dev/null
+++ b/component/qt/buildout.cfg
@@ -0,0 +1,61 @@
+[buildout]
+
+parts = 
+  qt
+  
+[qt]
+recipe = slapos.recipe.build
+slapos_promisee =
+  file:plop
+
+# Online installer
+x86 = http://get.qt.nokia.com/qtsdk/Qt_SDK_Lin32_online_v1_1_3_en.run eae2e2a1396fec1369b66c71d7df6eab
+x86-64 =  http://get.qt.nokia.com/qtsdk/Qt_SDK_Lin64_online_v1_1_3_en.run a4d929bc4d6511290c07c3745477b77b
+# Offline installer
+#x86 = http://get.qt.nokia.com/qtsdk/Qt_SDK_Lin32_offline_v1_1_3_en.run 106fdae4ec8947c491ab0a827a02da12
+#x86-64 = http://get.qt.nokia.com/qtsdk/Qt_SDK_Lin64_offline_v1_1_3_en.run 8c280beb11ee763840464572ed80e8b8
+
+# Needs many dependencies.
+
+script =
+  if not self.options.get('url'): self.options['url'], self.options['md5sum'] = self.options[guessPlatform()].split(' ')
+  download_file = self.download(self.options['url'], self.options.get('md5sum'))
+  extract_dir = tempfile.mkdtemp(self.name)
+  os.chdir(extract_dir)
+  (download_dir, filename) = os.path.split(download_file)
+  auto_extract_bin = os.path.join(extract_dir, filename)
+  shutil.move(download_file, auto_extract_bin)
+  os.chmod(auto_extract_bin, 0777)
+  subprocess.call([auto_extract_bin])
+  self.cleanup_dir_list.append(extract_dir)
+  workdir = guessworkdir(extract_dir)
+  import pdb; pdb.set_trace()
+  self.copyTree(os.path.join(workdir, "jre1.6.0_27"), "%(location)s")
+
+
+
+#ldd qt.run
+#	linux-gate.so.1 =>  (0xb7827000)
+#	libutil.so.1 => /lib/i686/cmov/libutil.so.1 (0xb781c000)
+#	libgobject-2.0.so.0 => not found
+#	libSM.so.6 => not found
+#	libICE.so.6 => not found
+#	libXrender.so.1 => not found
+#	libfontconfig.so.1 => not found
+#	libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0xb77a4000)
+#	libz.so.1 => /usr/lib/libz.so.1 (0xb778f000)
+#	libXext.so.6 => /usr/lib/libXext.so.6 (0xb7780000)
+#	libX11.so.6 => /usr/lib/libX11.so.6 (0xb7663000)
+#	libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb765f000)
+#	libgthread-2.0.so.0 => not found
+#	librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7655000)
+#	libglib-2.0.so.0 => not found
+#	libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb763c000)
+#	libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb754d000)
+#	libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7527000)
+#	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7508000)
+#	libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb73c2000)
+#	libxcb.so.1 => /usr/lib/libxcb.so.1 (0xb73a9000)
+#	/lib/ld-linux.so.2 (0xb7828000)
+#	libXau.so.6 => /usr/lib/libXau.so.6 (0xb73a6000)
+#	libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0xb73a1000)
\ No newline at end of file
diff --git a/component/xorg/buildout.cfg b/component/xorg/buildout.cfg
index 8807f69e9817de7d1b60454444b9cd405b1bf9a9..9258a76ce07248887351550c8c1630c9e8069051 100644
--- a/component/xorg/buildout.cfg
+++ b/component/xorg/buildout.cfg
@@ -1,12 +1,13 @@
-# Minimalistict xorg
 [buildout]
 extends =
   ../freetype/buildout.cfg
+  ../intltool/buildout.cfg
   ../libuuid/buildout.cfg
   ../libxml2/buildout.cfg
   ../libxslt/buildout.cfg
   ../pkgconfig/buildout.cfg
   ../zlib/buildout.cfg
+  ../openssl/buildout.cfg
 
 parts =
   libXdmcp
@@ -31,6 +32,8 @@ configure-options =
   --disable-specs
   --without-xmlto
   --without-fop
+environment =
+  PATH=${libxml2:location}/bin:${pkgconfig:location}/bin:%(PATH)s
 
 [xextproto]
 recipe = hexagonit.recipe.cmmi
@@ -49,6 +52,8 @@ configure-options =
   --disable-docs
   --without-xmlto
   --without-fop
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
 
 [libXau]
 recipe = hexagonit.recipe.cmmi
@@ -95,6 +100,9 @@ url = http://www.x.org/releases/X11R7.6/src/lib/libXext-1.2.0.tar.bz2
 md5sum = 9bb236ff0193e9fc1c1fb504dd840331
 environment =
   PKG_CONFIG_PATH=${xcbproto:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig
+  CPPFLAGS=-I${xcbproto:location}/include -I${libXau:location}/include -I${xproto:location}/include -I${xorg-libpthread-stubs:location}/include -I${xextproto:location}/include -I${libX11:location}/include -I${libxcb:location}/include
+  LD_LIBRARY_PATH=${xcbproto:location}/lib:${libXau:location}/lib:${xorg-libpthread-stubs:location}/lib:${xextproto:location}/lib:${libX11:location}/lib:${libxcb:location}/lib
+  LD_RUN_PATH=${xcbproto:location}/lib:${libXau:location}/lib:${xorg-libpthread-stubs:location}/lib:${xextproto:location}/lib:${libX11:location}/lib:${libxcb:location}/lib
   PATH=${pkgconfig:location}/bin:%(PATH)s
 # Warning: do *not* enable -fPIC CFLAGS for this library. Even if it fails and ld asks you to enable it. This will not solve your problem, and create an unexpected (by build chain) setup (all .o will be position-independant code).
 # CFLAGS=-fPIC
@@ -116,6 +124,16 @@ download-only = true
 filename = 700c7896b832d6e4fb0185f0d5382b01f94e7141.patch
 md5sum = 52635ef694ee6f1acb642a77ee8eb010
 
+[inputproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/inputproto-2.0.1.tar.bz2
+md5sum = da9bf9e5d174163f597d2d72757d9038
+
+[kbproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/kbproto-1.0.5.tar.bz2
+md5sum = e7edb59a3f54af15f749e8f3e314ee62
+
 [libX11]
 recipe = hexagonit.recipe.cmmi
 url = http://www.x.org/releases/X11R7.6/src/lib/libX11-1.4.0.tar.bz2
@@ -126,14 +144,19 @@ configure-options =
   --disable-composecache
   --disable-xcms
   --disable-xf86bigfont
-  --disable-xkb
   --disable-specs
   --without-xmlto
   --without-fop
 environment =
-  PKG_CONFIG_PATH=${xproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig
+  PKG_CONFIG_PATH=${xproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${inputproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig
+  LD_LIBRARY_PATH=${xproto:location}/lib:${xextproto:location}/lib:${libxcb:location}/lib
+  LD_RUN_PATH=${xproto:location}/lib:${xextproto:location}/lib:${libxcb:location}/lib
   PATH=${pkgconfig:location}/bin:%(PATH)s
 
+
+# Below is stuff for xserver
+
+
 [libXdmcp]
 recipe = hexagonit.recipe.cmmi
 url = http://www.x.org/releases/X11R7.6/src/lib/libXdmcp-1.1.0.tar.bz2
@@ -146,11 +169,147 @@ configure-options =
   --without-xmlto
   --without-fop
 
+[fixesproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/fixesproto-4.1.2.tar.bz2
+md5sum = bdb58ecc313b509247036d5c11fa99df
+
+[bigreqsproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/bigreqsproto-1.1.1.tar.bz2
+md5sum = 6f6c24436c2b3ab235eb14a85b9aaacf
+
+[xcmiscproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/xcmiscproto-1.2.1.tar.bz2
+md5sum = cd7372cd827bfd7ca7e9238f2ce274b1
+
+[damageproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/damageproto-1.2.1.tar.bz2
+md5sum = 998e5904764b82642cc63d97b4ba9e95
+
+[randrproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/randrproto-1.3.2.tar.bz2
+md5sum = 597491c0d8055e2a66f11350c4985775
+
+[renderproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/renderproto-0.11.1.tar.bz2
+md5sum = a914ccc1de66ddeb4b611c6b0686e274
+
+[videoproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/videoproto-2.3.1.tar.bz2
+md5sum = c3b348c6e2031b72b11ae63fc7f805c2
+
+[fontsproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/fontsproto-2.1.1.tar.bz2
+md5sum = 37102ffcaa73f77d700acd6f7a25d8f0
+
+[recordproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/recordproto-1.14.1.tar.bz2
+md5sum = 24541a30b399213def35f48efd926c63
+
+[resourceproto]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/resourceproto-1.1.1.tar.bz2
+md5sum = 8ff0525ae7502b48597b78d00bc22284
+
 [xineramaproto]
 recipe = hexagonit.recipe.cmmi
-url = http://www.x.org/releases/X11R7.6/src/proto/xineramaproto-1.2.tar.bz2
+url = http://www.x.org/releases/X11R7.6/src/everything/xineramaproto-1.2.tar.bz2
 md5sum = a8aadcb281b9c11a91303e24cdea45f5
 
+[pixman]
+recipe = hexagonit.recipe.cmmi
+url = http://xorg.freedesktop.org/archive/individual/lib/pixman-0.23.2.tar.bz2 
+md5sum = 2e2805f5ca02edeb15a7862779670069
+
+[libfontenc]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/libfontenc-1.1.0.tar.bz2
+md5sum = 11d3c292f05a90f6f67840a9e9c3d9b8
+environment =
+  PKG_CONFIG_PATH=${xproto:location}/lib/pkgconfig
+  LD_LIBRARY_PATH=${xproto:location}/lib/
+  LD_RUN_PATH=${xproto:location}/lib/
+  CPPFLAGS=-I${xproto:location}/include/ -I${zlib:location}/include
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+
+[libXfont]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/libXfont-1.4.3.tar.bz2
+md5sum = 6fb689cfe13d8d9460f4abb5bd88588d
+environment =
+  PKG_CONFIG_PATH=${fontsproto:location}/lib/pkgconfig:${libfontenc:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig:${freetype:location}/lib/pkgconfig
+  LD_LIBRARY_PATH=${fontsproto:location}/lib:${libfontenc:location}/lib:${xtrans:location}/include/:${xproto:location}/lib/:${freetype:location}/lib
+  LD_RUN_PATH=${fontsproto:location}/lib:${libfontenc:location}/lib:${xproto:location}/lib/:${xtrans:location}/include/:${freetype:location}/lib
+  LDFLAGS=-L${zlib:location}/lib
+  CPPFLAGS=-I${zlib:location}/include
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+
+[libxkbfile]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/everything/libxkbfile-1.0.7.tar.bz2
+md5sum = 59b4fe0bdf8d9b05e45b59e8fe9e7516
+environment =
+  PKG_CONFIG_PATH=${kbproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig
+  LD_LIBRARY_PATH=${kbproto:location}/lib:${libX11:location}/lib:${xproto:location}/lib/
+  LD_RUN_PATH=${kbproto:location}/lib:${libX11:location}/lib:${xproto:location}/lib/
+  CPPFLAGS=-I${xproto:location}/include/ -I${libX11:location}/include/ -I${kbproto:location}/include
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+
+[xkeyboard-config]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/individual/data/xkeyboard-config/xkeyboard-config-2.1.tar.bz2
+md5sum = 57ecc78bacd8ecc398d8ed6588f4d04b
+depends =
+  ${perl:version}
+  ${perl-XML-Parser:location}
+configure-options =
+  --disable-static
+  --enable-shared
+  --enable-compat-rules
+  --with-xkb-rules-symlink=xfree86
+environment =
+  PATH=${gettext:location}/bin:${intltool:location}/bin:${perl:location}/bin:${pkgconfig:location}/bin:${xkbcomp:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${libX11:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig
+
+[xkbcomp]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/app/xkbcomp-1.2.0.tar.bz2
+md5sum = 0f55995cd8da9b2d88553e1a2e17cd0a
+# Hardcoded location for xkeyboard-config, needed during compile time
+xkeyboard-config-location = ${libxkbfile:location}/../xkeyboard-config/share/X11/xkb
+configure-options =
+  --with-xkb-config-root=${:xkeyboard-config-location}
+environment =
+  PKG_CONFIG_PATH=${libxkbfile:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libxcb:location}/lib/pkgconfig:${xorg-libpthread-stubs:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig
+  LD_LIBRARY_PATH=${libxkbfile:location}/lib/:${libX11:location}/lib
+  LD_RUN_PATH=${libxkbfile:location}/lib/:${libX11:location}/lib
+  CPPFLAGS=-I${libxkbfile:location}/include/ -I${libX11:location}/include -I${xproto:location}/include -I${kbproto:location}/include
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+
+[render]
+recipe = hexagonit.recipe.cmmi
+url = http://xlibs.freedesktop.org/release/renderext-0.9.tar.bz2
+md5sum = d43c2afc69937655d13c02588c9ff974
+
+[libXrender]
+recipe = hexagonit.recipe.cmmi
+url = http://xlibs.freedesktop.org/release/libXrender-0.9.0.tar.bz2
+md5sum = ce7cda009aa0b10a73637941d44ae789
+environment =
+  PKG_CONFIG_PATH=${render:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig
+  CPPFLAGS=-I${libX11:location}/include/ -I${xproto:location}/include -I${kbproto:location}/include
+  LD_LIBRARY_PATH=${render:location}/lib:${libX11:location}/lib
+  LD_RUN_PATH=${render:location}/lib
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+
 [libXinerama]
 recipe = hexagonit.recipe.cmmi
 url = http://www.x.org/releases/X11R7.6/src/lib/libXinerama-1.1.1.tar.bz2
@@ -185,3 +344,104 @@ environment =
   PKG_CONFIG_PATH=${libICE:location}/lib/pkgconfig:${libuuid:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig
   PATH=${pkgconfig:location}/bin:%(PATH)s
   LIBUUID_CFLAGS=-I${libuuid:location}/include
+
+[libXt]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/lib/libXt-1.0.9.tar.bz2
+md5sum = 8a414f8f2327aaa616ca2dcac1f5d8c3
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+    PKG_CONFIG_PATH=${render:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${libSM:location}/lib/pkgconfig:${libICE:location}/lib/pkgconfig
+    CPPFLAGS=-I${xproto:location}/include -I${libX11:location}/include -I${libSM:location}/include -I${libICE:location}/include -I${kbproto:location}/include
+
+
+[dri2proto]
+recipe = hexagonit.recipe.cmmi
+url = http://xorg.freedesktop.org/releases/individual/proto/dri2proto-2.6.tar.gz
+md5sum = 873142af5db695537cfe05e01d13541f
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${xorg-libpthread-stubs:location}/lib/pkgconfig
+
+
+[pciaccess]
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/lib/libpciaccess-0.12.0.tar.bz2
+md5sum = 285e07976274572e1f1e68edee09b70a
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+
+[makedepend]
+recipe = hexagonit.recipe.cmmi
+url = http://xorg.freedesktop.org/releases/individual/util/makedepend-1.0.3.tar.bz2
+md5sum = 4e6cb97bbecfbb34f3f644a75e513093
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${xproto:location}/lib/pkgconfig
+
+[glproto]
+recipe = hexagonit.recipe.cmmi
+url = http://xorg.freedesktop.org/releases/individual/proto/glproto-1.4.14.tar.bz2
+md5sum = f48257daf0017f7a7667e5bf48ca3578
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${xproto:location}/lib/pkgconfig
+
+[xfixes]
+recipe = hexagonit.recipe.cmmi
+url = http://xorg.freedesktop.org/releases/individual/lib/libXfixes-4.0.5.tar.bz2
+md5sum = 1b4b8386bd5d1751b2c7177223ad4629
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${xproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig
+  CPPFLAGS=-I${libX11:location}/include -I${xproto:location}/include -I${fixesproto:location}/include -I${xextproto:location}/include
+
+[xdamage]
+recipe = hexagonit.recipe.cmmi
+url = http://xorg.freedesktop.org/releases/individual/lib/libXdamage-1.1.3.tar.bz2
+md5sum = 44774e1a065158b52f1a0da5100cebec
+configure-options = 
+  --disable-static
+environment =
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  PKG_CONFIG_PATH=${damageproto:location}/lib/pkgconfig:${xfixes:location}/lib/pkgconfig:${fixesproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${libX11:location}/lib/pkgconfig
+  CPPFLAGS=-I${libX11:location}/include -I${xproto:location}/include -I${fixesproto:location}/include -I${xextproto:location}/include -I${damageproto:location}/include -I${xfixes:location}/include 
+
+[xserver]
+# Adds Xvfb functionnality
+recipe = hexagonit.recipe.cmmi
+url = http://www.x.org/releases/X11R7.6/src/xserver/xorg-server-1.9.3.tar.bz2
+md5sum = 5bef6839a76d029204ab31aa2fcb5201
+configure-options =
+  --enable-xvfb
+  --disable-aiglx
+  --disable-composite
+  --disable-screensaver
+  --disable-glx
+  --disable-dri
+  --disable-dri2
+  --disable-xorg
+  --disable-xprint
+  --disable-config-hal
+  --with-xkb-bin-directory=${xkbcomp:location}/bin
+  --with-xkb-path=${xkeyboard-config:location}/share/X11/xkb
+#XXX-Cedric : The following can be safely removed as soon as Xvfb is known as working
+#  --with-default-font-path="${xfree86-fonts:location}/share/fonts/X11/Type1,${fontutil:location}/share/fonts/X11/75dpi,${cursor-fonts:location}/share/fonts/X11/misc"
+#depends = ${adobe-75dpi-fonts:location}
+environment =
+  PKG_CONFIG_PATH=${pixman:location}/lib/pkgconfig:${openssl:location}/lib/pkgconfig:${xorg-util-macros:location}/share/pkgconfig:${fixesproto:location}/lib/pkgconfig:${damageproto:location}/lib/pkgconfig:${xcmiscproto:location}/lib/pkgconfig:${xtrans:location}/share/pkgconfig:${bigreqsproto:location}/lib/pkgconfig:${xproto:location}/lib/pkgconfig:${randrproto:location}/lib/pkgconfig:${renderproto:location}/lib/pkgconfig:${xextproto:location}/lib/pkgconfig:${inputproto:location}/lib/pkgconfig:${kbproto:location}/lib/pkgconfig:${fontsproto:location}/lib/pkgconfig:${videoproto:location}/lib/pkgconfig:${recordproto:location}/lib/pkgconfig:${resourceproto:location}/lib/pkgconfig:${xineramaproto:location}/lib/pkgconfig:${libXau:location}/lib/pkgconfig:${libxkbfile:location}/lib/pkgconfig:${libXfont:location}/lib/pkgconfig
+  CPPFLAGS=-I${xproto:location}/include -I${pixman:location}/include/pixman-1 -I${xextproto:location}/include -I${inputproto:location}/include -I${fontsproto:location}/include -I${kbproto:location}/include -I${xineramaproto:location}/include -I${renderproto:location}/include -I${bigreqsproto:location}/include -I${videoproto:location}/include -I${resourceproto:location}/include -I${xcmiscproto:location}/include -I${xtrans:location}/include -I${libXau:location}/include -I${randrproto:location}/include -I${libxkbfile:location}/include -I${recordproto:location}/include -I${fixesproto:location}/include -I${damageproto:location}/include
+  PATH=${pkgconfig:location}/bin:%(PATH)s
+  LDFLAGS=-Wl,-rpath,${openssl:location}/lib
diff --git a/setup.py b/setup.py
index d962e124ec62381aaee978795727c734197ba6d2..10cdeec329e8d1e2a491e0c83618e80404c4c34f 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
 import glob
 import os
 
-version = '0.39-dev'
+version = '0.40-dev'
 name = 'slapos.cookbook'
 long_description = open("README.txt").read() + "\n" + \
     open("CHANGES.txt").read() + "\n"
@@ -89,6 +89,7 @@ setup(name=name,
           'pwgen = slapos.recipe.pwgen:Recipe',
           'proactive = slapos.recipe.proactive:Recipe',
           'request = slapos.recipe.request:Recipe',
+          'seleniumrunner = slapos.recipe.seleniumrunner:Recipe',
           'sheepdogtestbed = slapos.recipe.sheepdogtestbed:SheepDogTestBed',
           'shell = slapos.recipe.shell:Recipe',
           'shellinabox = slapos.recipe.shellinabox:Recipe',
diff --git a/slapos/recipe/README.seleniumrunner.txt b/slapos/recipe/README.seleniumrunner.txt
new file mode 100644
index 0000000000000000000000000000000000000000..eec75eeba3277c1d178475eea69ab2f556745297
--- /dev/null
+++ b/slapos/recipe/README.seleniumrunner.txt
@@ -0,0 +1,24 @@
+seleniumrunner
+==========
+Allows to run selenium tests through browser and xvfb. Posts the results on
+Nexedi ERP5.
+
+Parameters
+=====
+  * project : name of the project inside of ERP5 test result instance
+  * user : username to use in ERP5 instance to test
+  * password : password to use in ERP5 instance to test
+  * suite_name : name of test suite to launch 
+  * url : url to portal_test of ERP5 isntance to test
+  * test_report_instance_url : url of test_result_module to put results
+
+  * Example :
+    <?xml version="1.0" encoding="utf-8"?>
+    <instance>
+    <parameter id="project">Vifib</parameter>
+    <parameter id="user">myuser</parameter>
+    <parameter id="password">mypassword</parameter>
+    <parameter id="suite_name">my_zuite</parameter>
+    <parameter id="url">https://myerp5totest/erp5/portal_tests</parameter>
+    <parameter id="test_report_instance_url">https://user:passwordwww.myerp5withtestresults.com/test_result_module/</parameter>
+    </instance>
diff --git a/slapos/recipe/pulse2/__init__.py b/slapos/recipe/pulse2/__init__.py
index 62e05a4ba85d042692d42082d32188b93d1c9d36..a1deec9cefeba853d29e95ee571ce0220c9053a5 100644
--- a/slapos/recipe/pulse2/__init__.py
+++ b/slapos/recipe/pulse2/__init__.py
@@ -267,7 +267,7 @@ class Recipe(BaseSlapRecipe):
         memcached_ip=config['memcached_ip'],
         memcached_port=config['memcached_port'])
   
-    def createHtdocs(self, source, document_root):
+  def createHtdocs(self, source, document_root):
     source = self.options['source'].strip()
     document_root = self.createDataDirectory('htdocs')
     for p in os.listdir(document_root):
diff --git a/slapos/recipe/seleniumrunner/ERP5TypeFunctionalTestCase.py b/slapos/recipe/seleniumrunner/ERP5TypeFunctionalTestCase.py
new file mode 100644
index 0000000000000000000000000000000000000000..c4e57b9bee259b67bda17d358e3eaf347c229d3f
--- /dev/null
+++ b/slapos/recipe/seleniumrunner/ERP5TypeFunctionalTestCase.py
@@ -0,0 +1,356 @@
+##############################################################################
+#
+# Copyright (c) 2011 Nexedi SARL and Contributors. All Rights Reserved.
+#                     Kazuhiko <kazuhiko@nexedi.com>
+#                     Rafael Monnerat <rafael@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+# XXX-Cedric : This is an import of 
+# http://git.erp5.org/gitweb/erp5.git/blob/HEAD:/product/ERP5Type/tests/ERP5TypeFunctionalTestCase.py
+# Modification of the present file should be ported back to this original file.
+import os
+import time
+import signal
+import re
+from subprocess import Popen, PIPE
+import shutil
+
+#from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase, \
+#                                               _getConversionServerDict
+
+# REGEX FOR ZELENIUM TESTS
+TEST_PASS_RE = re.compile('<th[^>]*>Tests passed</th>\n\s*<td[^>]*>([^<]*)')
+TEST_FAILURE_RE = re.compile('<th[^>]*>Tests failed</th>\n\s*<td[^>]*>([^<]*)')
+IMAGE_RE = re.compile('<img[^>]*?>')
+TEST_ERROR_TITLE_RE = re.compile('(?:error.gif.*?>|title status_failed"><td[^>]*>)([^>]*?)</td></tr>', re.S)
+TEST_RESULT_RE = re.compile('<div style="padding-top: 10px;">\s*<p>\s*'
+                          '<img.*?</div>\s.*?</div>\s*', re.S)
+
+TEST_ERROR_RESULT_RE = re.compile('.*(?:error.gif|title status_failed).*', re.S)
+
+ZELENIUM_BASE_URL = "%s/portal_tests/%s/core/TestRunner.html?test=../test_suite_html&auto=on&resultsUrl=%s/portal_tests/postResults&__ac_name=%s&__ac_password=%s"
+
+tests_framework_home = os.path.dirname(os.path.abspath(__file__))
+# handle 'system global' instance
+if tests_framework_home.startswith('/usr/lib'):
+  real_instance_home = '/var/lib/erp5'
+else:
+  real_instance_home = os.path.sep.join(
+    tests_framework_home.split(os.path.sep)[:-3])
+
+instance_home = os.path.join(real_instance_home, 'unit_test')
+bt5_dir_list = ','.join([
+                    os.path.join(instance_home, 'Products/ERP5/bootstrap'),
+                    os.path.join(instance_home, 'bt5')])
+
+class TimeoutError(Exception):
+  pass
+
+class Xvfb:
+  def __init__(self, fbdir, xvfb_location="Xvfb"):
+    self.display_list = [":%s" % i for i in range(123, 144)]
+    self.display = None
+    self.fbdir = fbdir
+    self.pid = None
+    self.xvfb_location = xvfb_location
+
+  def _runCommand(self, display):
+    command = [self.xvfb_location, '-fbdir' , self.fbdir, display]
+    self.process = Popen(" ".join(command),
+                         stdout=PIPE,
+                         stderr=PIPE,
+                         shell=True,
+                         close_fds=True)
+
+  def run(self):
+    for display_try in self.display_list:
+      lock_filepath = '/tmp/.X%s-lock' % display_try.replace(":", "")
+      if not os.path.exists(lock_filepath):
+        self._runCommand(display_try)
+        self.display = display_try
+        break
+
+    #display = os.environ.get('DISPLAY')
+    #if display:
+    #  auth = Popen(['xauth', 'list', display], stdout=PIPE).communicate()[0]
+    #  if auth:
+    #    (displayname, protocolname, hexkey) = auth.split()
+    #    Popen(['xauth', 'add', 'localhost/unix:%s' % display, protocolname, hexkey])
+
+    print 'Xvfb : %d' % self.process.pid
+    print 'Take screenshots using xwud -in %s/Xvfb_screen0' % self.fbdir
+
+  def quit(self):
+    if hasattr(self, 'process'):
+      process_pid = self.process.pid
+      try:
+        self.process.terminate()
+      finally:
+        if process_pid:
+          print "Stopping Xvfb on pid: %s" % self.pid
+          os.kill(process_pid, signal.SIGTERM)
+
+class Browser:
+
+  use_xvfb = 1
+  def __init__(self, profile_dir, host, bin_location=None):
+    self.bin_location = bin_location
+    self.profile_dir = profile_dir
+    self.host = host
+    self.pid = None
+
+  def quit(self):
+    if self.pid:
+      os.kill(self.pid, signal.SIGTERM)
+
+  def _run(self, url, display):
+    """ This method should be implemented on a subclass """
+    raise NotImplementedError
+
+  def _setEnviron(self):
+    pass
+
+  def run(self, url, display):
+    self.clean()
+    self._setEnviron()
+    self._setDisplay(display)
+    self._run(url)
+    print "Browser %s running on pid: %s" % (self.__class__.__name__, self.pid)
+
+  def clean(self):
+    """ Clean up removing profile dir and recreating it"""
+    os.system("rm -rf %s" % self.profile_dir)
+    os.mkdir(self.profile_dir)
+
+  def _createFile(self, filename, content):
+    file_path = os.path.join(self.profile_dir, filename)
+    with open(file_path, 'w') as f:
+      f.write(content)
+    return file_path
+
+  def _setDisplay(self, display):
+    if display is None:
+      try:
+        shutil.copy2(os.path.expanduser('~/.Xauthority'), '%s/.Xauthority' % self.profile_dir)
+      except IOError:
+        pass
+    else:
+      os.environ["DISPLAY"] = display
+
+  def _runCommand(self, command_tuple):
+    print " ".join(list(command_tuple))
+    self.pid = os.spawnlp(os.P_NOWAIT, *command_tuple)
+
+class Firefox(Browser):
+  """ Use firefox to open run all the tests"""
+
+  def _setEnviron(self):
+    os.environ['MOZ_NO_REMOTE'] = '1'
+    os.environ['HOME'] = self.profile_dir
+    os.environ['LC_ALL'] = 'C'
+    os.environ["MOZ_CRASHREPORTER_DISABLE"] = "1"
+    os.environ["NO_EM_RESTART"] = "1"
+
+  def _run(self, url):
+    # Prepare to run
+    if not self.bin_location:
+      self.bin_location = "firefox"
+    self._createFile('prefs.js', self.getPrefJs())
+    self._runCommand((self.bin_location, "firefox", "-no-remote",
+                     "-profile", self.profile_dir, url))
+
+    os.environ['MOZ_NO_REMOTE'] = '0'
+
+  def getPrefJs(self):
+    return """
+// Don't ask if we want to switch default browsers
+user_pref("browser.shell.checkDefaultBrowser", false);
+
+// Disable pop-up blocking
+user_pref("browser.allowpopups", true);
+user_pref("dom.disable_open_during_load", false);
+
+// Configure us as the local proxy
+//user_pref("network.proxy.type", 2);
+
+// Disable security warnings
+user_pref("security.warn_submit_insecure", false);
+user_pref("security.warn_submit_insecure.show_once", false);
+user_pref("security.warn_entering_secure", false);
+user_pref("security.warn_entering_secure.show_once", false);
+user_pref("security.warn_entering_weak", false);
+user_pref("security.warn_entering_weak.show_once", false);
+user_pref("security.warn_leaving_secure", false);
+user_pref("security.warn_leaving_secure.show_once", false);
+user_pref("security.warn_viewing_mixed", false);
+user_pref("security.warn_viewing_mixed.show_once", false);
+
+// Disable "do you want to remember this password?"
+user_pref("signon.rememberSignons", false);
+
+// increase the timeout before warning of unresponsive script
+user_pref("dom.max_script_run_time", 120);
+
+// this is required to upload files
+user_pref("capability.principal.codebase.p1.granted", "UniversalFileRead");
+user_pref("signed.applets.codebase_principal_support", true);
+user_pref("capability.principal.codebase.p1.id", "http://%s");
+user_pref("capability.principal.codebase.p1.subjectName", "");""" % \
+    (self.host)
+
+class PhantomJS(Browser):
+  def _createRunJS(self):
+    run_js = """
+var page = new WebPage(),
+    address;
+
+address = phantom.args[0];
+page.open(address, function (status) {
+  if (status !== 'success') {
+    console.log('FAIL to load the address');
+  } else {
+    console.log('SUCCESS load the address');
+  }
+  phantom.exit();
+});
+"""
+    return self._createFile('run.js', run_js)
+
+  def _run(self, url):
+    self._runCommand(("phantomjs", "phantomjs", self._createRunJS(), url))
+
+class FunctionalTestRunner:
+
+  # There is no test that can take more them 24 hours
+  timeout = 2.0 * 60 * 60
+
+  def __init__(self, host, port, portal, run_only='', use_phanthom=False):
+    self.instance_home = os.environ['INSTANCE_HOME']
+
+    # Such informations should be automatically loaded
+    self.user = 'ERP5TypeTestCase'
+    self.password = ''
+    self.run_only = run_only
+    profile_dir = os.path.join(self.instance_home, 'profile')
+    self.portal = portal
+    if use_phanthom:
+      self.browser = PhantomJS(profile_dir, host, int(port))
+    else:
+      self.browser = Firefox(profile_dir, host, int(port))
+
+  def getStatus(self):
+    transaction.commit()
+    return self.portal.portal_tests.TestTool_getResults()
+
+  def _getTestURL(self):
+    return ZELENIUM_BASE_URL % (self.portal.portal_url(), self.run_only,
+                      self.portal.portal_url(), self.user, self.password)
+
+  def test(self, debug=0):
+    xvfb = Xvfb(self.instance_home)
+    try:
+      start = time.time()
+      if not debug and self.browser.use_xvfb:
+        xvfb.run()
+      self.browser.run(self._getTestURL() , xvfb.display)
+      while self.getStatus() is None:
+        time.sleep(10)
+        if (time.time() - start) > float(self.timeout):
+          raise TimeoutError("Test took more them %s seconds" % self.timeout)
+
+    finally:
+      self.browser.quit()
+      xvfb.quit()
+
+  def processResult(self):
+    file_content = self.getStatus().encode("utf-8", "replace")
+    sucess_amount = TEST_PASS_RE.search(file_content).group(1)
+    failure_amount = TEST_FAILURE_RE.search(file_content).group(1)
+    error_title_list = [re.compile('\s+').sub(' ', x).strip()
+                    for x in TEST_ERROR_TITLE_RE.findall(file_content)]
+
+    detail = ''
+    for test_result in TEST_RESULT_RE.findall(file_content):
+      if  TEST_ERROR_RESULT_RE.match(test_result):
+        detail += test_result
+
+    detail = IMAGE_RE.sub('', detail)
+    if detail:
+      detail = IMAGE_RE.sub('', detail)
+      detail = '''<html>
+<head>
+ <style type="text/css">tr.status_failed { background-color:red };</style>
+</head>
+<body>%s</body>
+</html>''' % detail
+
+    # When return fix output for handle unicode issues.
+    return detail, int(sucess_amount), int(failure_amount), error_title_list
+
+class ERP5TypeFunctionalTestCase:
+  run_only = ""
+  foreground = 0
+  use_phanthom = False
+
+  def getTitle(self):
+    return "Zelenium"
+
+  def afterSetUp(self):
+    # create browser_id_manager
+    if not "browser_id_manager" in self.portal.objectIds():
+      self.portal.manage_addProduct['Sessions'].constructBrowserIdManager()
+    transaction.commit()
+    self.setSystemPreference()
+    self.portal.portal_tests.TestTool_cleanUpTestResults()
+    self.stepTic()
+
+  def setSystemPreference(self):
+    conversion_dict = _getConversionServerDict()
+    self.portal.Zuite_setPreference(
+       working_copy_list=bt5_dir_list,
+       conversion_server_hostname=conversion_dict['hostname'],
+       conversion_server_port=conversion_dict['port']
+      )
+    # XXX Memcached is missing
+    # XXX Persistent cache setup is missing
+
+  def testFunctionalTestRunner(self):
+    # first of all, abort to get rid of the mysql participation inn this
+    # transaction
+    self.portal._p_jar.sync()
+    self.runner = FunctionalTestRunner(self.serverhost, self.serverport,
+                                self.portal, self.run_only, self.use_phanthom)
+
+    self.runner.test(debug=self.foreground)
+    detail, success, failure, error_title_list = self.runner.processResult()
+
+    self.logMessage("-" * 79)
+    total = success + failure
+    self.logMessage("%s Functional Tests %s Tests, %s Failures" % \
+                    (self.getTitle(), total, failure))
+    self.logMessage("-" * 79)
+    self.logMessage(detail)
+    self.logMessage("-" * 79)
+    self.assertEquals([], error_title_list)
diff --git a/slapos/recipe/seleniumrunner/__init__.py b/slapos/recipe/seleniumrunner/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..813fb0d4709a3e798cb07bd7f9a34842e88e1643
--- /dev/null
+++ b/slapos/recipe/seleniumrunner/__init__.py
@@ -0,0 +1,107 @@
+##############################################################################
+#
+# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# guarantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 3
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+#############################################################################
+
+import os
+import sys
+import zc.buildout
+from slapos.recipe.librecipe import BaseSlapRecipe
+
+class Recipe(BaseSlapRecipe):
+  def _install(self):
+    """Set the connection dictionnary for the computer partition and create a list
+    of paths to the different wrappers."""
+    self.path_list = []
+    self.requirements, self.ws = self.egg.working_set()
+
+    self.installTestrunner(self.getDisplay())
+    self.linkBinary()
+
+    return self.path_list
+
+  def getDisplay(self):
+    """Generate display id for the instance."""
+    display_list = [":%s" % i for i in range(123,144)]
+    for display_try in display_list:
+      lock_filepath = '/tmp/.X%s-lock' % display_try.replace(":", "")
+      if not os.path.exists(lock_filepath):
+        display = display_try
+        break
+    return display
+
+  def installTestrunner(self, display):
+    """Instanciate a wrapper for the browser and the test reports."""
+    arguments = dict(
+        xvfb_binary    = self.options['xvfb_binary'],
+        display        = display,
+        suite_name     = self.parameter_dict['suite_name'],
+        base_url       = self.parameter_dict['url'],
+        browser_argument_list = [],
+        user           = self.parameter_dict['user'],
+        password       = self.parameter_dict['password'],
+        project       = self.parameter_dict['project'],
+        test_report_instance_url = \
+            self.parameter_dict['test_report_instance_url'],
+        etc_directory  = self.etc_directory)
+
+    # Check wanted browser XXX-Cedric not yet used but can be useful
+    #if self.parameter_dict.get('browser', None) is None:
+    arguments['browser_binary'] = self.options['firefox_binary']
+    #elif self.parameter_dict['browser'].strip().lowercase() == 'chrome' or
+    #    self.parameter_dict['browser'].strip().lowercase() == 'chromium':
+    #  arguments['browser_binary'] = self.options['chromium_binary']
+    #  arguments['browser_argument_list'].extend['--ignore-certificate-errors',
+    #      option_translate = '--disable-translate',
+    #      option_security = '--disable-web-security']
+    #elif self.parameter_dict['browser'].strip().lowercase() == 'firefox':
+    #  arguments['browser_binary'] = self.options['firefox_binary']
+
+    self.path_list.extend(zc.buildout.easy_install.scripts([(
+        'testrunner',__name__+'.testrunner', 'run')], self.ws,
+        sys.executable, self.wrapper_directory,
+        arguments=[arguments]))
+
+  def linkBinary(self):
+    """Links binaries to instance's bin directory for easier exposal"""
+    for linkline in self.options.get('link_binary_list', '').splitlines():
+      if not linkline:
+        continue
+      target = linkline.split()
+      if len(target) == 1:
+        target = target[0]
+        path, linkname = os.path.split(target)
+      else:
+        linkname = target[1]
+        target = target[0]
+      link = os.path.join(self.bin_directory, linkname)
+      if os.path.lexists(link):
+        if not os.path.islink(link):
+          raise zc.buildout.UserError(
+            'Target link already %r exists but it is not link' % link)
+        os.unlink(link)
+      os.symlink(target, link)
+      self.logger.debug('Created link %r -> %r' % (link, target))
+      self.path_list.append(link)
diff --git a/slapos/recipe/seleniumrunner/erp5functionaltestreporthandler.py b/slapos/recipe/seleniumrunner/erp5functionaltestreporthandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..18aa5ccad712995dec5262a07fefcbf3ee1db75b
--- /dev/null
+++ b/slapos/recipe/seleniumrunner/erp5functionaltestreporthandler.py
@@ -0,0 +1,187 @@
+##############################################################################
+#
+# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# guarantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 3
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+#############################################################################
+
+import re
+import urlparse
+import urllib
+import httplib
+import mimetools
+from random import randint
+import tempfile
+import os
+import stat
+import zipfile
+import mimetypes
+import datetime
+
+TB_SEP = "============================================================="\
+    "========="
+
+# REGEX FOR ZELENIUM TESTS
+TEST_PASS_RE = re.compile('<th[^>]*>Tests passed</th>\n\s*<td[^>]*>([^<]*)')
+TEST_FAILURE_RE = re.compile('<th[^>]*>Tests failed</th>\n\s*<td[^>]*>([^<]*)')
+IMAGE_RE = re.compile('<img[^>]*?>')
+TEST_ERROR_TITLE_RE = re.compile('(?:error.gif.*?>|title status_failed"><td[^>]*>)([^>]*?)</td></tr>', re.S)
+TEST_RESULT_RE = re.compile('<div style="padding-top: 10px;">\s*<p>\s*'
+                          '<img.*?</div>\s.*?</div>\s*', re.S)
+DURATION_RE = re.compile('<th[^>]*>Elapsed time \(sec\)</th>\n\s*<td[^>]*>([^<]*)')
+
+TEST_ERROR_RESULT_RE = re.compile('.*(?:error.gif|title status_failed).*', re.S)
+
+def get_content_type(f):
+  return mimetypes.guess_type(f.name)[0] or 'application/octet-stream'
+
+class ConnectionHelper:
+  def __init__(self, url):
+    self.conn = urlparse.urlparse(url)
+    if self.conn.scheme == 'http':
+      connection_type = httplib.HTTPConnection
+      if self.conn.port is None:
+        self.port = 80
+    else:
+      connection_type = httplib.HTTPSConnection
+      if self.conn.port is None:
+        self.port = 443
+    self.connection_type = connection_type
+
+  def _connect(self):
+    self.connection = self.connection_type(self.conn.hostname + ':' +
+        str(self.conn.port or self.port))
+
+  def POST(self, path, parameter_dict, file_list=None):
+    self._connect()
+    parameter_dict.update(__ac_name=self.conn.username,
+                          __ac_password=self.conn.password)
+    header_dict = {'Content-type': "application/x-www-form-urlencoded"}
+    if file_list is None:
+      body = urllib.urlencode(parameter_dict)
+    else:
+      boundary = mimetools.choose_boundary()
+      header_dict['Content-type'] = 'multipart/form-data; boundary=%s' % (
+          boundary,)
+      body = ''
+      for k, v in parameter_dict.iteritems():
+        body += '--%s\r\n' % boundary
+        body += 'Content-Disposition: form-data; name="%s"\r\n' % k
+        body += '\r\n'
+        body += '%s\r\n' % v
+      for name, filename in file_list:
+        f = open(filename, 'r')
+        body += '--%s\r\n' % boundary
+        body += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n'\
+                % (name, name)
+        body += 'Content-Type: %s\r\n' % get_content_type(f)
+        body += 'Content-Length: %d\r\n' % os.fstat(f.fileno())[stat.ST_SIZE]
+        body += '\r\n'
+        body += f.read()
+        f.close()
+        body += '\r\n'
+    self.connection.request("POST", self.conn.path + '/' + path,
+          body, header_dict)
+    self.response = self.connection.getresponse()
+
+
+class ERP5TestReportHandler:
+  def __init__(self, url, suite_name):
+    # random test id
+    self.test_id = "%s-%X" % (
+       ("%s" % datetime.date.today()).replace("-", ""),
+       randint(1, 10000000000000000),
+     )
+    self.connection_helper = ConnectionHelper(url)
+    self.suite_name = suite_name
+
+  def reportStart(self):
+    # report that test is running
+    print 'Starting test with id %s' % self.test_id
+    self.connection_helper.POST('TestResultModule_reportRunning', dict(
+      test_suite=self.suite_name,
+      test_report_id=self.test_id,
+      ))
+
+  def reportFinished(self, out_file):
+    # make file parsable by erp5_test_results
+    out_file, success, failure, duration = self.processResult(out_file)
+
+    # XXX-Cedric : make correct display in test_result_module
+    tempcmd = tempfile.mkstemp()[1]
+    tempcmd2 = tempfile.mkstemp()[1]
+    tempout = tempfile.mkstemp()[1]
+    templog = tempfile.mkstemp()[1]
+    tl = open(templog, 'w')
+    tl.write(TB_SEP + '\n')
+    tl.write(out_file)
+
+    tl.write("----------------------------------------------------------------------\n")
+    tl.write('Ran 1 test in %.2fs\n' % duration)
+    if success:
+      tl.write('OK\n')
+    else:
+      tl.write('FAILED (failures=1)\n')
+    tl.write(TB_SEP + '\n')
+    tl.close()
+    open(tempcmd, 'w').write(""" %s""" % self.suite_name)
+    # create nice zip archive
+    tempzip = tempfile.mkstemp()[1]
+    # XXX-Cedric : support multiple tests
+    zip = zipfile.ZipFile(tempzip, 'w')
+    zip.write(tempout, '%s/001/stdout' % self.suite_name)
+    zip.write(templog, '%s/001/stderr' % self.suite_name)
+    zip.write(tempcmd, '%s/001/cmdline' % self.suite_name)
+    zip.close()
+    os.unlink(templog)
+    os.unlink(tempcmd)
+    os.unlink(tempout)
+    os.unlink(tempcmd2)
+
+    # post it to ERP5
+    self.connection_helper.POST('TestResultModule_reportCompleted',
+        dict(test_report_id=self.test_id), file_list=[('filepath', tempzip)])
+    os.unlink(tempzip)
+
+  def processResult(self, out_file):
+    file_content = out_file
+    sucess_amount = TEST_PASS_RE.search(file_content).group(1)
+    failure_amount = TEST_FAILURE_RE.search(file_content).group(1)
+    error_title_list = [re.compile('\s+').sub(' ', x).strip()
+                    for x in TEST_ERROR_TITLE_RE.findall(file_content)]
+    duration = DURATION_RE.search(file_content).group(1)
+    detail = ''
+    for test_result in TEST_RESULT_RE.findall(file_content):
+      if  TEST_ERROR_RESULT_RE.match(test_result):
+        detail += test_result
+
+    detail = IMAGE_RE.sub('', detail)
+    if detail:
+      detail = IMAGE_RE.sub('', detail)
+      detail = '''<html>
+<head>
+ <style type="text/css">tr.status_failed { background-color:red };</style>
+</head>
+<body>%s</body>
+</html>''' % detail
+    return detail, int(sucess_amount), int(failure_amount), float(duration)
diff --git a/slapos/recipe/seleniumrunner/template/xvfb_run.in b/slapos/recipe/seleniumrunner/template/xvfb_run.in
new file mode 100644
index 0000000000000000000000000000000000000000..647e99ca5324ff8b2f553e849ab7c387fd51c4a3
--- /dev/null
+++ b/slapos/recipe/seleniumrunner/template/xvfb_run.in
@@ -0,0 +1,5 @@
+#!/bin/sh
+# BEWARE: This file is operated by slapgrid
+# BEWARE: It will be overwritten automatically
+
+%(xvfb_binary) :%(display) -screen %(display) 1024x768x24
\ No newline at end of file
diff --git a/slapos/recipe/seleniumrunner/testrunner.py b/slapos/recipe/seleniumrunner/testrunner.py
new file mode 100644
index 0000000000000000000000000000000000000000..99b95e8d9350e9c6654834c4d38c76d807141a5b
--- /dev/null
+++ b/slapos/recipe/seleniumrunner/testrunner.py
@@ -0,0 +1,138 @@
+##############################################################################
+#
+# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# guarantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 3
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+#############################################################################
+
+from datetime import datetime
+from erp5functionaltestreporthandler import ERP5TestReportHandler
+from ERP5TypeFunctionalTestCase import Xvfb, Firefox, TimeoutError
+from time import sleep
+import time
+import os
+import urllib2
+
+def run(args):
+  config = args[0]
+
+  test_url = assembleTestUrl(config['base_url'], config['suite_name'],
+      config['user'], config['password'])
+
+  # There is no test that can take more them 24 hours
+  timeout = 2.0 * 60 * 60
+  
+  while True:
+    erp5_report = ERP5TestReportHandler(config['test_report_instance_url'],
+        config['project'] + '@' + config['suite_name'])
+    try:
+      os.environ['DISPLAY'] = config['display']
+      xvfb = Xvfb(config['etc_directory'], config['xvfb_binary'])
+      profile_dir = os.path.join(config['etc_directory'], 'profile')
+      # XXX-Cedric : change Firefox prefs.js generation so that it can take a
+      #              list of websites supposed to be reached instead of config['base_url']
+      browser = Firefox(profile_dir, config['base_url'], config['browser_binary'])
+      try:
+        start = time.time()
+        xvfb.run()
+        profile_dir = os.path.join(config['etc_directory'], 'profile')
+        browser.run(test_url , xvfb.display)
+        erp5_report.reportStart()
+        while not isTestFinished(config['base_url']):
+          time.sleep(10)
+          print("Test not finished yet.")
+          if (time.time() - start) > float(timeout):
+            raise TimeoutError("Test took more than %s seconds" % timeout)
+      except TimeoutError:
+        continue
+      finally:
+        browser.quit()
+        xvfb.quit()
+      print("Test has finished and Firefox has been killed.")
+      
+      erp5_report.reportFinished(getStatus(config['base_url']).encode("utf-8",
+          "replace"))
+      
+      
+      print("Test finished and report sent, sleeping.")
+    except urllib2.URLError, urlError:
+        print "Error: %s" % urlError.msg
+    sleep(3600)
+
+def openUrl(url):
+    # Send Accept-Charset headers to activate the UnicodeConflictResolver
+    # (imitating firefox 3.5.9 here)
+    headers = { 'Accept-Charset' : 'ISO-8859-1,utf-8;q=0.7,*;q=0.7' }
+    request = urllib2.Request(url, headers=headers)
+    # Try to use long timeout, this is needed when there is many
+    # activities runing
+    try:
+      f = urllib2.urlopen(request, timeout=3600*4)
+    except TypeError:
+      f = urllib2.urlopen(request)
+    file_content = f.read()
+    f.close()
+    return file_content
+
+def isTestFinished(url):
+  """Fetch latest report. If report has been created less than 60 seconds ago,
+  it must be the current one.
+  Return true if test is finished, else return false.
+  """
+  latest_report = openUrl('%s/portal_tests/TestTool_getLatestReportId/' % url)
+  if latest_report is '':
+    return False
+  latest_report_date = latest_report[7:]
+  time_delta = datetime.now() - \
+      datetime.strptime(latest_report_date, '%Y%m%d_%H%M%S' )
+  if time_delta.days is not 0:
+    return False
+  if time_delta.seconds < 120:
+    return True
+  return False
+
+def getStatus(url):
+    try:
+      # Try 5 times.
+      for i in range(5):
+        try:
+          status = openUrl('%s/portal_tests/TestTool_getResults/' % (url))
+          break
+        except urllib2.URLError, urlError:
+          if i is 4: raise
+          print("Warning : %s while getting status" % urlError.msg)
+    except urllib2.HTTPError, e:
+      if e.msg == "No Content":
+        status = ""
+      else:
+        raise
+    return status
+
+def assembleTestUrl(base_url, suite_name, user, password):
+      """
+      Create the full url to the testrunner
+      """
+      test_url = "%s/%s/core/TestRunner.html?test=../test_suite_html&"\
+          "resultsUrl=%s/postResults&auto=on&__ac_name=%s&__ac_password=%s" % (
+          base_url, suite_name, base_url, user, password)
+      return test_url
\ No newline at end of file
diff --git a/software/helloworld/instance.cfg b/software/helloworld/instance.cfg
deleted file mode 100644
index 6253979c658bcedc5da7ee89c73ae517c9a84294..0000000000000000000000000000000000000000
--- a/software/helloworld/instance.cfg
+++ /dev/null
@@ -1,9 +0,0 @@
-[buildout]
-parts =
-  dummy
-
-eggs-directory = ${buildout:eggs-directory}
-develop-eggs-directory = ${buildout:develop-eggs-directory}
-
-[dummy]
-recipe = slapos.recipe.dummy
diff --git a/software/helloworld/software.cfg b/software/helloworld/software.cfg
deleted file mode 100644
index c0719285e528862a17a26f1599696edf7b377c1e..0000000000000000000000000000000000000000
--- a/software/helloworld/software.cfg
+++ /dev/null
@@ -1,34 +0,0 @@
-[buildout]
-
-extensions +=
-  mr.developer
-# activates mr.developer
-auto-checkout = *
-versions = versions
-
-find-links += http://www.nexedi.org/static/packages/source/slapos.buildout/
-
-parts =
-  template
-  eggs
-
-unzip = true
-
-[sources]
-# XXX-Cedric : either publish the egg or use mr.developer properly, but DELETE
-# This repository and use slapos.recipe.helloworld.
-slapos.recipe.dummy = git git://github.com/WaterCooled/slapos.recipe.dummy.git
-
-[versions]	
-zc.buildout = 1.5.3-dev-SlapOS-001
-
-[template]
-recipe = slapos.recipe.template
-url = ${:_profile_base_location_}/instance.cfg
-output = ${buildout:directory}/template.cfg
-mode = 0644
-
-[eggs]
-recipe = zc.recipe.egg
-#eggs = slapos.recipe.helloworld
-eggs = slapos.recipe.dummy
diff --git a/software/kumofs/software.cfg b/software/kumofs/software.cfg
index 01dd3fe812e4a31cc9766c2e2d8b4c9c5f83f160..e4bdecad98dc52082ed72e24cae186ace56c43af 100644
--- a/software/kumofs/software.cfg
+++ b/software/kumofs/software.cfg
@@ -136,19 +136,16 @@ zope.interface = 3.8.0
 [networkcache]
 # Cedric de Saint Martin signature certificate
 signature-certificate-list =
-  -----BEGIN PRIVATE KEY-----
-  MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANqRqW69hpRtqjuX
-  maEl9cwKPSb/Vu170OUqaNrZYaMnAv1T3pTU8cob5IjuC/HUZiiX/OEIxIsRZuKO
-  H8visw4PQEqSbSKvqOmJONirzXDHyye0Sf9yDRyEubAzbRjsP7wQabAkHhvsUGTK
-  dALIIhoAVTGkDBMryxqMJ9MHzyLjAgMBAAECgYEAmtszIUvUqxsbzob1iTBc+wiS
-  FSw6CZ58/bDTg6Mawz6jppqii+5ntRuYCtAl1Fv5WW998m6E2kclDwVFT+45j0AO
-  JroHGY74Egy54Wl7D2hE5ldJKy4LL6bPdM+FQy3S46Ekc7OyStU2LmMmWHdVMlzx
-  p7UQJ8UeE/UiBj5hUBkCQQD23HriV7cuYqJLzP689CWvWFjjJFtpuJBtYve7aqNb
-  DsL5i64H0eMkDyQzYavZfZg7lO9KAy0PbofInXI9owPHAkEA4qkN5MUZQcNb3zRd
-  TtPdA8WWRuArnAN4U3BZPMHu2UQ9U9gWedY2NzzqYGLw4Hx7XH54fRExG2L35LyA
-  zD9wBQJAS42rZn7mJ6I0ffKdvIMUzZfCjLJh7/d27KOvooK+wG3CKtIfT3FjjXO8
-  5qTsDcKsxv+MRSC3t9NiZ3oYrtinnQJBAJBrozynEYbDkaBQ3ztA50xl83DJmT/Z
-  Piv8JAAAmc26G1F3GCsdgIIFwFkV8eE3r+qpcuBNufp3Pvhx26dIrHkCQQDzFZp4
-  VDhTCQQoEBrGXoz6TRzmGfu8VpQZMXdL7O6aGNVqQGfsWQS7Sh+8iXsOi2APTAjr
-  xUL3fZnXAjr6AnZC
-  -----END PRIVATE KEY-----
+  -----BEGIN CERTIFICATE-----
+  MIIB9jCCAV+gAwIBAgIJAO4V/jiMoICoMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
+  BAMMCENPTVAtMjMyMCAXDTEyMDIxNjExMTAyM1oYDzIxMTIwMTIzMTExMDIzWjAT
+  MREwDwYDVQQDDAhDT01QLTIzMjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
+  wi/3Z8W9pUiegUXIk/AiFDQ0UJ4JFAwjqr+HSRUirlUsHHT+8DzH/hfcTDX1I5BB
+  D1ADk+ydXjMm3OZrQcXjn29OUfM5C+g+oqeMnYQImN0DDQIOcUyr7AJc4xhvuXQ1
+  P2pJ5NOd3tbd0kexETa1LVhR6EgBC25LyRBRae76qosCAwEAAaNQME4wHQYDVR0O
+  BBYEFMDmW9aFy1sKTfCpcRkYnP6zUd1cMB8GA1UdIwQYMBaAFMDmW9aFy1sKTfCp
+  cRkYnP6zUd1cMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAskbFizHr
+  b6d3iIyN+wffxz/V9epbKIZVEGJd/6LrTdLiUfJPec7FaxVCWNyKBlCpINBM7cEV
+  Gn9t8mdVQflNqOlAMkOlUv1ZugCt9rXYQOV7rrEYJBWirn43BOMn9Flp2nibblby
+  If1a2ZoqHRxoNo2yTmm7TSYRORWVS+vvfjY=
+  -----END CERTIFICATE-----
diff --git a/software/mysql-5.1/software.cfg b/software/mysql-5.1/software.cfg
index 33335b62d17d397ecc864c8ca2bf68f9592afbed..30a7b97a4864290cc2fd3a4b2dddab24a4c5f9d8 100644
--- a/software/mysql-5.1/software.cfg
+++ b/software/mysql-5.1/software.cfg
@@ -134,20 +134,16 @@ zope.interface = 3.8.0
 [networkcache]
 # Cedric de Saint Martin signature certificate
 signature-certificate-list =
-  -----BEGIN PRIVATE KEY-----
-  MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANqRqW69hpRtqjuX
-  maEl9cwKPSb/Vu170OUqaNrZYaMnAv1T3pTU8cob5IjuC/HUZiiX/OEIxIsRZuKO
-  H8visw4PQEqSbSKvqOmJONirzXDHyye0Sf9yDRyEubAzbRjsP7wQabAkHhvsUGTK
-  dALIIhoAVTGkDBMryxqMJ9MHzyLjAgMBAAECgYEAmtszIUvUqxsbzob1iTBc+wiS
-  FSw6CZ58/bDTg6Mawz6jppqii+5ntRuYCtAl1Fv5WW998m6E2kclDwVFT+45j0AO
-  JroHGY74Egy54Wl7D2hE5ldJKy4LL6bPdM+FQy3S46Ekc7OyStU2LmMmWHdVMlzx
-  p7UQJ8UeE/UiBj5hUBkCQQD23HriV7cuYqJLzP689CWvWFjjJFtpuJBtYve7aqNb
-  DsL5i64H0eMkDyQzYavZfZg7lO9KAy0PbofInXI9owPHAkEA4qkN5MUZQcNb3zRd
-  TtPdA8WWRuArnAN4U3BZPMHu2UQ9U9gWedY2NzzqYGLw4Hx7XH54fRExG2L35LyA
-  zD9wBQJAS42rZn7mJ6I0ffKdvIMUzZfCjLJh7/d27KOvooK+wG3CKtIfT3FjjXO8
-  5qTsDcKsxv+MRSC3t9NiZ3oYrtinnQJBAJBrozynEYbDkaBQ3ztA50xl83DJmT/Z
-  Piv8JAAAmc26G1F3GCsdgIIFwFkV8eE3r+qpcuBNufp3Pvhx26dIrHkCQQDzFZp4
-  VDhTCQQoEBrGXoz6TRzmGfu8VpQZMXdL7O6aGNVqQGfsWQS7Sh+8iXsOi2APTAjr
-  xUL3fZnXAjr6AnZC
-  -----END PRIVATE KEY-----
-
+  -----BEGIN CERTIFICATE-----
+  MIIB9jCCAV+gAwIBAgIJAO4V/jiMoICoMA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
+  BAMMCENPTVAtMjMyMCAXDTEyMDIxNjExMTAyM1oYDzIxMTIwMTIzMTExMDIzWjAT
+  MREwDwYDVQQDDAhDT01QLTIzMjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
+  wi/3Z8W9pUiegUXIk/AiFDQ0UJ4JFAwjqr+HSRUirlUsHHT+8DzH/hfcTDX1I5BB
+  D1ADk+ydXjMm3OZrQcXjn29OUfM5C+g+oqeMnYQImN0DDQIOcUyr7AJc4xhvuXQ1
+  P2pJ5NOd3tbd0kexETa1LVhR6EgBC25LyRBRae76qosCAwEAAaNQME4wHQYDVR0O
+  BBYEFMDmW9aFy1sKTfCpcRkYnP6zUd1cMB8GA1UdIwQYMBaAFMDmW9aFy1sKTfCp
+  cRkYnP6zUd1cMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAskbFizHr
+  b6d3iIyN+wffxz/V9epbKIZVEGJd/6LrTdLiUfJPec7FaxVCWNyKBlCpINBM7cEV
+  Gn9t8mdVQflNqOlAMkOlUv1ZugCt9rXYQOV7rrEYJBWirn43BOMn9Flp2nibblby
+  If1a2ZoqHRxoNo2yTmm7TSYRORWVS+vvfjY=
+  -----END CERTIFICATE-----
diff --git a/software/seleniumrunner/instance.cfg b/software/seleniumrunner/instance.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..23d6d4683b891db94e1bbbfbabfababb4d37b6f7
--- /dev/null
+++ b/software/seleniumrunner/instance.cfg
@@ -0,0 +1,11 @@
+[buildout]
+parts =
+  seleniuminstance
+
+eggs-directory = ${buildout:eggs-directory}
+develop-eggs-directory = ${buildout:develop-eggs-directory} 
+
+[seleniuminstance]
+recipe = ${instance-recipe:egg}:${instance-recipe:module}
+xvfb_binary = ${xserver:location}/bin/Xvfb
+firefox_binary = ${firefox:location}/firefox-slapos
\ No newline at end of file
diff --git a/software/seleniumrunner/software.cfg b/software/seleniumrunner/software.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..c2333a1a197ed9c6cfc1e5496e65bbe4e1b5d586
--- /dev/null
+++ b/software/seleniumrunner/software.cfg
@@ -0,0 +1,52 @@
+[buildout]
+extensions = buildout-versions
+
+extends = 
+   ../../component/xorg/buildout.cfg
+   ../../component/lxml-python/buildout.cfg
+   ../../component/python-2.7/buildout.cfg
+   ../../component/firefox/buildout.cfg
+   ../../stack/shacache-client.cfg
+
+versions = versions
+
+find-links +=
+    http://www.nexedi.org/static/packages/source/slapos.buildout/
+
+parts =
+   template
+   eggs
+   instance-recipe-egg
+   xserver
+   firefox
+
+versions = versions
+
+unzip = true
+
+[instance-recipe]
+egg = slapos.cookbook
+module = seleniumrunner
+
+[instance-recipe-egg]
+recipe = zc.recipe.egg
+python = python2.7
+eggs = ${instance-recipe:egg}
+
+[eggs]
+recipe = zc.recipe.egg
+python = python2.7
+eggs =
+  ${lxml-python:egg}
+
+[template]
+# Default template for the instance.
+recipe = slapos.recipe.template
+url = ${:_profile_base_location_}/instance.cfg
+md5sum = 5fc198144831525a196d7394e4b15f80
+output = ${buildout:directory}/template.cfg
+mode = 0644
+
+[versions]
+# Use SlapOS patched zc.buildout
+zc.buildout = 1.5.3-dev-SlapOS-010