diff --git a/Common/Bindings.h b/Common/Bindings.h
index ce97aa4f3ffa57f7e18abd5364a39d38b69825f6..2a02084ef04701e8219987a3b3f7f05254f64893 100644
--- a/Common/Bindings.h
+++ b/Common/Bindings.h
@@ -1,521 +1,41 @@
 #ifndef _BINDINGS_H_
 #define _BINDINGS_H_
+#include <string>
+#include <list>
+#include <typeinfo>
 
-#ifndef HAVE_LUA //no bindings
-
-class methodBinding{};
-class constructorBinding{};
-template <class objectType, class returnType=void, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void>
-class methodBindingTemplate:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type,arg3Type);
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template <class objectType, class returnType, class arg0Type, class arg1Type, class arg2Type>
-class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,arg2Type,void>:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type);
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template <class objectType, class returnType, class arg0Type, class arg1Type>
-class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,void,void>:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type,arg1Type);
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template <class objectType, class returnType, class arg0Type>
-class methodBindingTemplate<objectType,returnType,arg0Type,void,void,void>:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type);
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template <class objectType, class returnType>
-class methodBindingTemplate<objectType,returnType,void,void,void,void>:public methodBinding {
-  typedef returnType (objectType::*callback)();
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template <class objectType, class arg0Type, class arg1Type, class arg2Type>
-class methodBindingTemplate<objectType,void,arg0Type,arg1Type,arg2Type,void>:public methodBinding {
-  typedef void (objectType::*callback)(arg0Type,arg1Type,arg2Type);
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template <class objectType, class arg0Type, class arg1Type>
-class methodBindingTemplate<objectType,void,arg0Type,arg1Type,void,void>:public methodBinding {
-  typedef void (objectType::*callback)(arg0Type,arg1Type);
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template <class objectType, class arg0Type>
-class methodBindingTemplate<objectType,void,arg0Type,void,void,void>:public methodBinding {
-  typedef void (objectType::*callback)(arg0Type);
+class methodBinding{
   public:
-  methodBindingTemplate(const std::string luaname,callback f){}
+  void setArgNames(std::string arg1, ...){}
+  void setDescription(std::string description){}
 };
-template <class objectType>
-class methodBindingTemplate<objectType,void,void,void,void,void>:public methodBinding {
-  typedef void (objectType::*callback)();
-  public:
-  methodBindingTemplate(const std::string luaname,callback f){}
-};
-template<class objectType, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void>
-class constructorBindingTemplate:public constructorBinding {};
-
-#else // HAVE_LUA
 
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
+// c++ does not allow to take pointer to constructor. We wrap the constructor with those function so that pointer to constructor-function are available.
+template <typename tObj, typename t0, typename t1, typename t2, typename t3> 
+tObj *constructorPtr(t0 a0, t1 a1, t2 a2, t3 a3){
+  return new tObj(a0,a1,a2,a3);
+}
+template <typename tObj, typename t0, typename t1, typename t2> 
+tObj *constructorPtr(t0 a0, t1 a1, t2 a2){
+  return new tObj(a0,a1,a2);
+}
+template <typename tObj, typename t0, typename t1> 
+tObj *constructorPtr(t0 a0, t1 a1){
+  return new tObj(a0,a1);
+}
+template <typename tObj, typename t0> 
+tObj *constructorPtr(t0 a0){
+  return new tObj(a0);
+}
+template <typename tObj> 
+tObj *constructorPtr(){
+  return new tObj();
 }
-#include <vector>
-
-
-class methodBinding {
-  public:
-  std::string _luaname;
-  virtual int call (lua_State *L)=0;
-  methodBinding(const std::string luaname){
-    _luaname=luaname;
-  }
-};
-
-class constructorBinding {
-  public:
-  virtual int call (lua_State *L)=0;
-};
-
-
-// this class is largely copied from luna
-// todo : add  reference to luna and check luna  licence
-template <typename T> class classBinding {
-  typedef struct { T *pT; bool owned;} userdataType;
-public:
-  static void push(lua_State *L, T* obj, bool owned) {
-    userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
-    ud->pT=obj;
-    ud->owned=owned;
-    luaL_getmetatable(L, T::className);  // lookup metatable in Lua registry
-    lua_setmetatable(L, -2);
-  }
-  static void Register(lua_State *L) {
-    lua_newtable(L);              
-    int methods = lua_gettop(L); //-- create methods , i.e. the class itself
-
-    luaL_newmetatable(L, T::className); 
-    int metatable = lua_gettop(L);     // -- create metatable of methods
-
-    // store method table in globals so that
-    // scripts can add functions written in Lua.
-    lua_pushstring(L, T::className);
-    lua_pushvalue(L, methods);
-    lua_settable(L, LUA_GLOBALSINDEX); // -- global[T::className] = methods
-
-//    lua_pushliteral(L, "__metatable");
-//    lua_pushvalue(L, methods);
-//    lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
-
-    lua_pushliteral(L, "__index");
-    lua_pushvalue(L, methods);
-    lua_settable(L, metatable);  // metatable.__index=methods
-
-    lua_pushliteral(L, "__tostring");
-    lua_pushcfunction(L, tostring_T);
-    lua_settable(L, metatable);
-
-    lua_pushliteral(L, "__gc");
-    lua_pushcfunction(L, gc_T);
-    lua_settable(L, metatable);
-
-    lua_newtable(L);                // mt for method table
-    int mt = lua_gettop(L);
-    lua_pushliteral(L, "__call");
-    lua_pushlightuserdata(L,(void*)T::constructorMethod);
-    lua_pushcclosure(L, callConstructor, 1);
-
-    lua_pushliteral(L, "new");
-    lua_pushvalue(L, -2);           // dup new_T function
-    lua_settable(L, methods);       // add new_T to method table
-    lua_settable(L, mt);            // mt.__call = new_T
-
-    if(T::parentClassName!=std::string("")){
-      lua_pushliteral(L,"__index");
-      lua_pushstring(L,T::parentClassName);
-      lua_gettable(L,LUA_GLOBALSINDEX);
-      lua_settable(L,mt);           // mt.__index = global[T::parentClassName] // this is the inheritance bit
-    }
-    lua_setmetatable(L, methods); // setmetatable(methods, mt)
-
-    // fill method table with methods from class T
-    for (methodBinding **l = T::methods; *l; l++) {
-      lua_pushstring(L, (*l)->_luaname.c_str());
-      lua_pushlightuserdata(L, (void*)*l);
-      lua_pushcclosure(L, callMethod, 1);
-      lua_settable(L, methods); //methods.(l->name) = callMethod(l)
-    } 
-    lua_pop(L, 2);  // drop metatable and method table
-  }
-
-  // get userdata from Lua stack and return pointer to T object
-  static T *check(lua_State *L, int narg) {
-    userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, narg));
-    if(!ud) luaL_typerror(L, narg, T::className);
-    return ud->pT;  // pointer to T object*/
-  }
-
-private:
-  classBinding();  // hide default constructor
-
-  // member function dispatcher
-  static int callMethod(lua_State *L) {
-    methodBinding *l = static_cast<methodBinding*>(lua_touserdata(L, lua_upvalueindex(1)));
-    return l->call(L);  // call member function
-  }
-  static int callConstructor(lua_State *L) {
-    constructorBinding *l = static_cast<constructorBinding*>(lua_touserdata(L, lua_upvalueindex(1)));
-    if(!l){
-      printf("this class does not have constructor\n");
-      //throw();
-    }
-    return l->call(L);  // call member function
-  }
-
-  // garbage collection metamethod
-  static int gc_T(lua_State *L) {
-    userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
-    /*if(ud->owned) //disable gc 
-      delete ud->pT;  // call destructor for T objects*/
-    return 0;
-  }
-
-  static int tostring_T (lua_State *L) {
-    char buff[32];
-    userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
-    T *t = static_cast<T*>(lua_touserdata(L, 1));
-    sprintf(buff, "%p", ud->pT);
-    lua_pushfstring(L, "%s (%s)", T::className, buff);
-    return 1;
-  }
-};
-
-template<class type>
-class lua_template {
-  public:
-  static type get(lua_State *L, int ia){
-    printf("error cannot get generic class in lua, only pointers are implemented\n");
-  }
-  static void push(lua_State *L, type obj){
-    printf("error cannot push generic class in lua, only pointers are implemented\n");
-  }
-};
-
-template <class type>
-class lua_template<type*>{
-  public:
-  static type* get(lua_State *L, int ia){
-    type *a=classBinding<type>::check(L,ia);
-    return a;
-
-  }
-  static void push(lua_State *L, type *obj){
-    classBinding<type>::push(L,obj,false);
-  }
-};
-
-template<>
-class lua_template<lua_State *>{
-  public:
-  static lua_State *get(lua_State *L, int ia){
-    return L;
-  }
-  static void push(lua_State *L, int i){
-    printf("error cannot push a lua_State in lua\n");
-  }
-};
-
-template<>
-class lua_template<int>{
-  public:
-  static int get(lua_State *L, int ia){
-    int a= luaL_checkint(L,ia);
-    return a;
-  }
-  static void push(lua_State *L, int i){
-    lua_pushinteger(L,i);
-  }
-};
-
-template<class type>
-class lua_template<std::vector<type > >{
-  public:
-  static std::vector<type>  get(lua_State *L, int ia){
-    std::vector<type> v;
-    size_t size=lua_objlen(L,ia);
-    v.resize(size);
-    for(size_t i=0;i<size;i++){
-      lua_pushinteger(L,i+1);
-      lua_gettable(L,ia);
-      v[i]=lua_template<type>::get(L,-1);
-      lua_pop(L,1);
-    }
-    return v;
-  }
-  static void push(lua_State *L, std::vector<type> a){
-  }
-};
-
-template<>
-class lua_template<double>{
-  public:
-  static double get(lua_State *L, int ia){
-    return luaL_checknumber(L,ia);
-  }
-  static void push(lua_State *L, double v){
-    lua_pushnumber(L,v);
-  }
-};
-
-template<>
-class lua_template<std::string>{
-  public:
-  static std::string get(lua_State *L, int ia){
-    return luaL_checkstring(L,ia);
-  }
-  static void push(lua_State *L, std::string s){
-    lua_pushstring(L,s.c_str());
-  }
-};
-
-//full : 4 args with return
-template <class objectType, class returnType=void, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void>
-class methodBindingTemplate:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type,arg3Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    arg1Type a1 = lua_template<arg1Type>::get(L,3);
-    arg2Type a2 = lua_template<arg2Type>::get(L,4);
-    arg3Type a3 = lua_template<arg3Type>::get(L,5);
-    returnType r=(obj->*(_f))(a0,a1,a2,a3);
-    lua_template<returnType>::push(L,r);
-    return 1;
-  }
-};
-//3 args with return
-template <class objectType, class returnType, class arg0Type, class arg1Type, class arg2Type>
-class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,arg2Type,void>:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    arg1Type a1 = lua_template<arg1Type>::get(L,3);
-    arg2Type a2 = lua_template<arg2Type>::get(L,4);
-    returnType r=(obj->*(_f))(a0,a1,a2);
-    lua_template<returnType>::push(L,r);
-    return 1;
-  }
-};
-//2 args with return
-template <class objectType, class returnType, class arg0Type, class arg1Type>
-class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,void,void>:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type,arg1Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    arg1Type a1 = lua_template<arg1Type>::get(L,3);
-    returnType r=(obj->*(_f))(a0,a1);
-    lua_template<returnType>::push(L,r);
-    return 1;
-  }
-};
-//1 arg with return
-template <class objectType, class returnType, class arg0Type>
-class methodBindingTemplate<objectType,returnType,arg0Type,void,void,void>:public methodBinding {
-  typedef returnType (objectType::*callback)(arg0Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    returnType r=(obj->*(_f))(a0);
-    lua_template<returnType>::push(L,r);
-    return 1;
-  }
-};
-//0 arg with return
-template <class objectType, class returnType>
-class methodBindingTemplate<objectType,returnType,void,void,void,void>:public methodBinding {
-  typedef returnType (objectType::*callback)();
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    returnType r=(obj->*(_f))();
-    lua_template<returnType>::push(L,r);
-    return 1;
-  }
-};
-//4 args without return
-template <class objectType, class arg0Type, class arg1Type, class arg2Type, class arg3Type>
-class methodBindingTemplate<objectType,void,arg0Type,arg1Type,arg2Type,arg3Type>:public methodBinding {
-  typedef void (objectType::*callback)(arg0Type,arg1Type,arg2Type,arg3Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    arg1Type a1 = lua_template<arg1Type>::get(L,3);
-    arg2Type a2 = lua_template<arg2Type>::get(L,4);
-    arg3Type a3 = lua_template<arg3Type>::get(L,5);
-    (obj->*(_f))(a0,a1,a2,a3);
-    return 0;
-  }
-};
-//3 args without return
-template <class objectType, class arg0Type, class arg1Type, class arg2Type>
-class methodBindingTemplate<objectType,void,arg0Type,arg1Type,arg2Type,void>:public methodBinding {
-  typedef void (objectType::*callback)(arg0Type,arg1Type,arg2Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    arg1Type a1 = lua_template<arg1Type>::get(L,3);
-    arg2Type a2 = lua_template<arg2Type>::get(L,4);
-    (obj->*(_f))(a0,a1,a2);
-    return 0;
-  }
-};
-//2 args without return
-template <class objectType, class arg0Type, class arg1Type>
-class methodBindingTemplate<objectType,void,arg0Type,arg1Type,void,void>:public methodBinding {
-  typedef void (objectType::*callback)(arg0Type,arg1Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    arg1Type a1 = lua_template<arg1Type>::get(L,3);
-    (obj->*(_f))(a0,a1);
-    return 0;
-  }
-};
-//1 arg without return
-template <class objectType, class arg0Type>
-class methodBindingTemplate<objectType,void,arg0Type,void,void,void>:public methodBinding {
-  typedef void (objectType::*callback)(arg0Type);
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,2);
-    (obj->*(_f))(a0);
-    return 0;
-  }
-};
-//0 arg without return
-template <class objectType>
-class methodBindingTemplate<objectType,void,void,void,void,void>:public methodBinding {
-  typedef void (objectType::*callback)();
-  callback _f;
-  public:
-  methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){
-    _f=f;
-  }
-  int call (lua_State *L) {
-    objectType *obj = classBinding<objectType>::check(L,1);
-    (obj->*(_f))();
-    return 0;
-  }
-};
 
-//constructor 4 args
-template<class objectType, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void>
-class constructorBindingTemplate:public constructorBinding {
-  int call (lua_State *L){
-    lua_remove(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,1);
-    arg1Type a1 = lua_template<arg1Type>::get(L,2);
-    arg2Type a2 = lua_template<arg2Type>::get(L,3);
-    arg3Type a3 = lua_template<arg3Type>::get(L,4);
-    classBinding<objectType>::push(L, new objectType(a0,a1,a2,a3),true);
-    return 1;
-  }
-};
-//constructor 3 args
-template<class objectType, class arg0Type, class arg1Type, class arg2Type>
-class constructorBindingTemplate<objectType,arg0Type,arg1Type,arg2Type,void>:public constructorBinding {
-  int call (lua_State *L){
-    lua_remove(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,1);
-    arg1Type a1 = lua_template<arg1Type>::get(L,2);
-    arg2Type a2 = lua_template<arg2Type>::get(L,3);
-    classBinding<objectType>::push(L, new objectType(a0,a1,a2),true);
-    return 1;
-  }
-};
-//constructor 2 args
-template<class objectType, class arg0Type, class arg1Type>
-class constructorBindingTemplate<objectType,arg0Type,arg1Type,void,void>:public constructorBinding {
-  int call (lua_State *L){
-    lua_remove(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,1);
-    arg1Type a1 = lua_template<arg1Type>::get(L,2);
-    classBinding<objectType>::push(L,new objectType(a0,a1),true);
-    return 1;
-  }
-};
-//constructor 1 args
-template<class objectType, class arg0Type>
-class constructorBindingTemplate<objectType,arg0Type,void,void,void>:public constructorBinding {
-  int call (lua_State *L){
-    lua_remove(L,1);
-    arg0Type a0 = lua_template<arg0Type>::get(L,1);
-    classBinding<objectType>::push(L, new objectType(a0),true);
-    return 1;
-  }
-};
-//constructor 0 args
-template<class objectType>
-class constructorBindingTemplate<objectType,void,void,void,void>:public constructorBinding {
-  int call (lua_State *L){
-    lua_remove(L,1);
-    classBinding<objectType>::push(L, new objectType(),true);
-    return 1;
-  }
-};
+#ifdef HAVE_LUA //no bindings
+#include "LuaBindings.h"
+#else
+#include "DummyBindings.h"
 #endif
+
 #endif
diff --git a/Common/DummyBindings.h b/Common/DummyBindings.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d5eceb5ec811e518353212b2cd86ae5d5335d8b
--- /dev/null
+++ b/Common/DummyBindings.h
@@ -0,0 +1,25 @@
+#ifndef _DUMMY_BINDINGS_H_
+#define _DUMMY_BINDINGS_H_
+class classBinding {
+public:
+  void setDescription(std::string description){};
+  template<typename parentType>
+  void setParentClass(){}
+  template <typename cb>
+  methodBinding *addMethod(std::string n, cb f){
+    return new methodBinding();
+  }
+  template <typename cb>
+  methodBinding *setConstructor(cb f){
+    return new methodBinding();
+  }
+};
+
+class binding {
+  public:
+  template<class t>
+  classBinding *addClass(std::string className){
+    return new classBinding();
+  }
+};
+#endif
diff --git a/Common/LuaBindings.cpp b/Common/LuaBindings.cpp
index 39259741777bb48b095d92a8fa0cfa705f89e221..b88a153fc3bc5ca46ab661c16b863e392c3eb902 100644
--- a/Common/LuaBindings.cpp
+++ b/Common/LuaBindings.cpp
@@ -23,7 +23,6 @@ void report_errors(lua_State *L, int status)
     lua_pop(L, 1); // remove error message
   }
 }
-
 int read_lua(const char *filename)
 {
   lua_State *L = lua_open();
@@ -34,20 +33,21 @@ int read_lua(const char *filename)
   luaopen_string(L);
   luaopen_math(L);
   luaopen_debug(L);
+  binding b;
+  b.L=L;
 
   // Register Lua bindings
-  classBinding<GModel>::Register(L);
-  classBinding<dgSystemOfEquations>::Register(L);
-  classBinding<dgBoundaryCondition>::Register(L);
-  classBinding<dgConservationLaw>::Register(L);
-  classBinding<dgConservationLawShallowWater2d>::Register(L);
-  classBinding<dgConservationLawAdvection>::Register(L);
-  classBinding<dgConservationLawWaveEquation>::Register(L);
-  classBinding<dgPerfectGasLaw2d>::Register(L);
-  classBinding<fullMatrix<double> >::Register(L);
-  classBinding<function>::Register(L);
-  classBinding<functionLua>::Register(L);
-  classBinding<functionConstant>::Register(L);
+  GModel::registerBindings(&b);
+  dgSystemOfEquations::registerBindings(&b);
+  dgBoundaryCondition::registerBindings(&b);
+  dgConservationLaw::registerBindings(&b);
+  dgConservationLawShallowWater2dRegisterBindings(&b);
+  dgConservationLawWaveEquationRegisterBindings(&b);
+  dgConservationLawAdvectionRegisterBindings(&b);
+  dgPerfectGasLaw2dRegisterBindings(&b);
+  fullMatrix<double>::registerBindings(&b);
+  function::registerBindings(&b);
+  functionLua::registerBindings(&b);
   function::registerDefaultFunctions();
 
   int s = luaL_loadfile(L, filename);
diff --git a/Common/LuaBindings.h b/Common/LuaBindings.h
index f70c09cef3dba27ee43430b1d21f0c8c920eecde..6ef329eceb49687248c8f2d3ea78dafcf70daae3 100644
--- a/Common/LuaBindings.h
+++ b/Common/LuaBindings.h
@@ -1,6 +1,421 @@
 #ifndef _LUA_BINDINGS_H_
 #define _LUA_BINDINGS_H_
+#include "Bindings.h"
 #ifdef HAVE_LUA
 int read_lua(const char *filename);
+
+extern "C" {
+#include "lua.h"
+#include "lauxlib.h"
+}
+#include <vector>
+
+
+/*** store a unique static class name for each binded class ***/
+template <typename type>
+class className{
+  static std::string _name;
+  public:
+  static void set(std::string name){
+    if(_name!="")
+      throw;
+    _name=name;
+  }
+  static const std::string &get(){
+    if(_name=="")
+      throw;
+    return _name;
+  }
+};
+template<typename type>
+std::string  className<type>::_name;
+
+
+
+
+/*** lua Stack : templates to get/push value from/on the lua stack ***/
+
+template<class type>
+class luaStack {
+  public:
+  static type get(lua_State *L, int ia){
+    printf("error cannot get generic class in lua, only pointers are implemented\n");
+  }
+  static void push(lua_State *L, type obj){
+    printf("error cannot push generic class in lua, only pointers are implemented\n");
+  }
+};
+
+template<>
+class luaStack<lua_State *>{
+  public:
+  static lua_State *get(lua_State *L, int ia){
+    return L;
+  }
+  static void push(lua_State *L, int i){
+    printf("error cannot push a lua_State in lua\n");
+  }
+};
+
+template<>
+class luaStack<int>{
+  public:
+  static int get(lua_State *L, int ia){
+    int a= luaL_checkint(L,ia);
+    return a;
+  }
+  static void push(lua_State *L, int i){
+    lua_pushinteger(L,i);
+  }
+};
+
+template<class type>
+class luaStack<std::vector<type > >{
+  public:
+  static std::vector<type>  get(lua_State *L, int ia){
+    std::vector<type> v;
+    size_t size=lua_objlen(L,ia);
+    v.resize(size);
+    for(size_t i=0;i<size;i++){
+      lua_pushinteger(L,i+1);
+      lua_gettable(L,ia);
+      v[i]=luaStack<type>::get(L,-1);
+      lua_pop(L,1);
+    }
+    return v;
+  }
+  static void push(lua_State *L, std::vector<type> a){
+  }
+};
+
+template<>
+class luaStack<double>{
+  public:
+  static double get(lua_State *L, int ia){
+    return luaL_checknumber(L,ia);
+  }
+  static void push(lua_State *L, double v){
+    lua_pushnumber(L,v);
+  }
+};
+
+template<>
+class luaStack<std::string>{
+  public:
+  static std::string get(lua_State *L, int ia){
+    return luaL_checkstring(L,ia);
+  }
+  static void push(lua_State *L, std::string s){
+    lua_pushstring(L,s.c_str());
+  }
+};
+
+template <typename type>
+class luaStack<type *>{
+  typedef struct { type *pT;} userdataType;
+  public:
+  static type* get(lua_State *L, int ia){
+    userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, ia));
+    if(!ud) luaL_typerror(L, ia, className<type>::get().c_str());
+    return ud->pT; 
+  }
+  static void push(lua_State *L,type *obj){
+    userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
+    ud->pT=obj;
+    luaL_getmetatable(L,className<type>::get().c_str());  // lookup metatable in Lua registry
+    lua_setmetatable(L, -2);
+  }
+};
+template <typename type>
+class luaStack<const type *>{
+  typedef struct { type *pT;} userdataType;
+  public:
+  static type* get(lua_State *L, int ia){
+    userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, ia));
+    if(!ud) luaL_typerror(L, ia, className<type>::get().c_str());
+    return ud->pT; 
+  }
+  static void push(lua_State *L,const type *obj){
+    userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
+    ud->pT=(type*)obj;
+    luaL_getmetatable(L,className<type>::get().c_str());  // lookup metatable in Lua registry
+    lua_setmetatable(L, -2);
+  }
+};
+
+/*** template to call c function from the lua stack ***/
+//static, return (only used for  contructor now)
+template < typename tRet, typename t0, typename t1, typename t2, typename t3>
+static int luaCall(lua_State *L,tRet (*_f)(t0,t1,t2,t3)) {
+  lua_remove(L,1);
+  luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2),luaStack<t2>::get(L,3),luaStack<t3>::get(L,4)));
+  return 1;
+};
+template < typename tRet, typename t0, typename t1, typename t2>
+static int luaCall(lua_State *L,tRet (*_f)(t0,t1,t2)) {
+  lua_remove(L,1);
+  luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2),luaStack<t2>::get(L,3)));
+  return 1;
+};
+template < typename tRet, typename t0, typename t1>
+static int luaCall(lua_State *L,tRet (*_f)(t0,t1)) {
+  lua_remove(L,1);
+  luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2)));
+  return 1;
+};
+template < typename tRet, typename t0>
+static int luaCall(lua_State *L,tRet (*_f)(t0)) {
+  lua_remove(L,1);
+  luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1)));
+  return 1;
+};
+template < typename tRet>
+static int luaCall(lua_State *L,tRet (*_f)()) {
+  lua_remove(L,1);
+  luaStack<tRet>::push(L,(*(_f))());
+  return 1;
+};
+
+//const, return
+template <typename tObj, typename tRet, typename t0, typename t1, typename t2, typename t3>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2,t3) const) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5)));
+  return 1;
+};
+template <typename tObj, typename tRet, typename t0, typename t1, typename t2>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2) const) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4)));
+  return 1;
+};
+template <typename tObj, typename tRet, typename t0, typename t1>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1) const) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3)));
+  return 1;
+};
+template <typename tObj, typename tRet, typename t0>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0) const) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2)));
+  return 1;
+};
+template <typename tObj, typename tRet>
+static int luaCall(lua_State *L,tRet (tObj::*_f)() const) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))());
+  return 1;
+};
+
+//non const, return
+template <typename tObj, typename tRet, typename t0, typename t1, typename t2, typename t3>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2,t3)) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5)));
+  return 1;
+};
+template <typename tObj, typename tRet, typename t0, typename t1, typename t2>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2)) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4)));
+  return 1;
+};
+template <typename tObj, typename tRet, typename t0, typename t1>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1)) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3)));
+  return 1;
+};
+template <typename tObj, typename tRet, typename t0>
+static int luaCall(lua_State *L,tRet (tObj::*_f)(t0)) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2)));
+  return 1;
+};
+template <typename tObj, typename tRet>
+static int luaCall(lua_State *L,tRet (tObj::*_f)()) {
+  luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))());
+  return 1;
+};
+
+//const, no return
+template <typename tObj, typename t0, typename t1, typename t2, typename t3>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2,t3) const) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5));
+  return 0;
+};
+template <typename tObj, typename t0, typename t1, typename t2>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2) const) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4));
+  return 0;
+};
+template <typename tObj, typename t0, typename t1>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1) const) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3));
+  return 0;
+};
+template <typename tObj, typename t0>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0) const) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2));
+  return 0;
+};
+template <typename tObj>
+static int luaCall(lua_State *L,void (tObj::*_f)() const) {
+  (luaStack<tObj*>::get(L,1)->*(_f))();
+  return 0;
+};
+
+//non const, no return
+template <typename tObj, typename t0, typename t1, typename t2, typename t3>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2,t3)) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5));
+  return 0;
+};
+template <typename tObj, typename t0, typename t1, typename t2>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2)) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4));
+  return 0;
+};
+template <typename tObj, typename t0, typename t1>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1)) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3));
+  return 0;
+};
+template <typename tObj, typename t0>
+static int luaCall(lua_State *L,void (tObj::*_f)(t0)) {
+  (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2));
+  return 0;
+};
+template <typename tObj>
+static int luaCall(lua_State *L,void (tObj::*_f)()) {
+  (luaStack<tObj*>::get(L,1)->*(_f))();
+  return 0;
+};
+
+/*** actual bindings classes ***/
+class luaMethodBinding :public methodBinding{
+  public:
+  std::string _luaname;
+  virtual int call (lua_State *L)=0;
+  luaMethodBinding(const std::string luaname){
+    _luaname=luaname;
+  }
+};
+
+template <typename cb>
+class methodBindingT:public luaMethodBinding {
+  public:
+  cb _f;
+  methodBindingT(const std::string luaname,cb f):luaMethodBinding(luaname){
+    _f=f;
+  }
+  int call (lua_State *L) {
+    return luaCall(L,_f);
+  }
+};
+
+
+class classBinding {
+  std::string _className;
+  lua_State *_L;
+  static int callMethod(lua_State *L) {
+    return  static_cast<luaMethodBinding*>(lua_touserdata(L, lua_upvalueindex(1)))->call(L); 
+  }
+  //I'd like to remove the "luaMethodBinding" and the "methodBindingT" classes and use this callback insteak
+  //but for some reason I don't understand, it does not work
+  static int callMethod2(lua_State *L) {
+    int (*f)(lua_State*,void *)=(int (*)(lua_State*,void*))(lua_touserdata(L,lua_upvalueindex(1)));
+    void *ff=lua_touserdata(L,lua_upvalueindex(2));
+    return (*f)(L,ff);
+  }
+  static int tostring (lua_State *L) {
+    typedef struct {void *pt;} userdata;
+    char buff[32];
+    const char *name = luaL_checkstring(L,lua_upvalueindex(1));
+    userdata *ud = static_cast<userdata*>(lua_touserdata(L, 1));
+    sprintf(buff, "%p", ud->pt);
+    lua_pushfstring(L, "%s (%s)", name, buff);
+    return 1;
+  }
+public:
+  // get userdata from Lua stack and return pointer to T object
+  classBinding(lua_State *L, std::string name){
+    _L=L;
+    _className=name;
+
+    // there are 3 tables involved :
+    // methods : the table of the C++ functions we bind (exept constructor)
+    // metatable : the metatable attached to each intance of the class, falling back to method (metatable.__index=method)
+    // mt : the metatable of method to store the constructor (__new) and possibly falling back to the parent metatable( __index)
+    lua_newtable(L); // methods  
+    int methods = lua_gettop(L);
+    lua_pushvalue(L, methods);
+    lua_setglobal(L, _className.c_str()); // global[_className] = methods
+
+    luaL_newmetatable(L, _className.c_str());
+    int metatable = lua_gettop(L);
+
+    lua_pushvalue(L, methods);
+    lua_setfield(L, metatable,"__index"); // metatable.__index=methods
+
+    lua_pushstring(L,name.c_str());
+    lua_pushcclosure(L, tostring,1);
+    lua_setfield(L, metatable,"__tostring");
+
+    lua_newtable(L);
+    int mt = lua_gettop(L);
+
+    lua_setmetatable(L, methods); // setmetatable(methods, mt)
+    lua_pop(L, 2);  // drop metatable and method table
+  } 
+  template<typename parentType>
+  void setParentClass(){
+    std::string parentClassName=className<parentType>::get();
+    lua_getglobal(_L,_className.c_str());
+    lua_getmetatable(_L,-1);
+    int mt=lua_gettop(_L);
+    lua_getglobal(_L,parentClassName.c_str());
+    lua_setfield(_L,mt,"__index");// mt.__index = global[_parentClassName] // this is the inheritance bit
+    lua_pop(_L,2);
+  }
+  void setDescription(std::string description){};
+
+  template <typename cb>
+  methodBinding *addMethod(std::string n, cb f){
+    luaMethodBinding *mb = new methodBindingT<cb>(n,f);
+
+    lua_getglobal(_L,_className.c_str());
+    int methods=lua_gettop(_L);
+    /*int (*lc)(lua_State *,cb)=(int(*)(lua_State*,cb))luaCall;
+    lua_pushlightuserdata(_L, (void*)lc);
+    lua_pushlightuserdata(_L, (void*)f);
+    lua_pushcclosure(_L, callMethod2, 2);*/
+    lua_pushlightuserdata(_L, (void*)mb);
+    lua_pushcclosure(_L, callMethod, 1);
+    lua_setfield(_L,methods, n.c_str()); //className.name = callMethod(mb)
+    lua_pop(_L,1);
+    return mb; 
+  }
+  template <typename cb>
+  methodBinding *setConstructor(cb f){
+    luaMethodBinding *_constructorMethod = new methodBindingT<cb>("constructor",f);
+
+    lua_getglobal(_L,_className.c_str());
+    int methods = lua_gettop(_L);
+    lua_getmetatable(_L,methods);
+    int mt = lua_gettop(_L);
+    lua_pushlightuserdata(_L,(void*)_constructorMethod);
+    lua_pushcclosure(_L, callMethod, 1);
+    lua_setfield(_L, mt,"__call");
+    lua_pop(_L,2);
+    return _constructorMethod;
+  }
+};
+
+class binding {
+  public:
+  lua_State *L;
+  template<class t>
+  classBinding *addClass(std::string className);
+};
+
+template<typename t>
+classBinding *binding::addClass(std::string name){
+  className<t>::set(name);
+  classBinding *cb=new classBinding(L,name);
+  return cb;
+}
 #endif
 #endif
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 453dae3999666308c496b6715564a7d3d0268136..3b2617342aa51335ffba6df3fdcad1d92f4d5ba1 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1380,13 +1380,12 @@ void GModel::save(std::string fileName){
 
 #ifdef HAVE_LUA
 #include "Bindings.h"
-const char GModel::className[]="GModel";
-const char GModel::parentClassName[]="";
-methodBinding *GModel::methods[]={
-  new methodBindingTemplate<GModel,int,int>("mesh",&GModel::mesh),
-  new methodBindingTemplate<GModel,void,std::string>("load",&GModel::load),
-  new methodBindingTemplate<GModel,void,std::string>("save",&GModel::save),
-  0
-};
-constructorBinding *GModel::constructorMethod=new constructorBindingTemplate<GModel>();
+void GModel::registerBindings(binding *b){
+  classBinding *cb = b->addClass<GModel>("GModel");
+  methodBinding *cm;
+  cm = cb->addMethod("mesh",&GModel::mesh);
+  cm = cb->addMethod("load",&GModel::load);
+  cm = cb->addMethod("save",&GModel::save);
+  cb->setConstructor(constructorPtr<GModel>);
+}
 #endif
diff --git a/Geo/GModel.h b/Geo/GModel.h
index aa025f734c91a6ce02749393403263fbc4ac604b..7aab300314ef13a9ea3afd663bb68fabf2e9a0f7 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -19,11 +19,6 @@
 #include "SBoundingBox3d.h"
 #include "discreteFace.h"
 
-#ifdef HAVE_LUA
-  class methodBinding;
-  class constructorBinding;
-#endif
-
 class Octree;
 class FM_Internals;
 class GEO_Internals;
@@ -33,6 +28,7 @@ class FieldManager;
 class CGNSOptions;
 class gLevelset;
 class discreteFace;
+class binding;
 
 // A geometric model. The model is a "not yet" non-manifold B-Rep.
 class GModel
@@ -445,12 +441,7 @@ class GModel
   void save(std::string fileName);
   void load(std::string fileName);
 
-#ifdef HAVE_LUA
-  static const char className[];
-  static const char parentClassName[];
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
-#endif
+  static void registerBindings(binding *b);
 };
 
 #endif
diff --git a/Numeric/fullMatrix.cpp b/Numeric/fullMatrix.cpp
index 2b169cb54851a34c6aec2c82a07a7f7eee0fb5dd..d660be5003baa5e8a07bddd3f4ca0df51972cfbf 100644
--- a/Numeric/fullMatrix.cpp
+++ b/Numeric/fullMatrix.cpp
@@ -289,28 +289,16 @@ bool fullMatrix<double>::svd(fullMatrix<double> &V, fullVector<double> &S)
   return false;
 }
 
-#if defined(HAVE_LUA)
 #include "Bindings.h"
 template<>
-const char fullMatrix<double>::className[]="fullMatrix";
-template<>
-const char fullMatrix<float>::className[]="fullMatrixFloat";
-template<>
-const char fullMatrix<double>::parentClassName[]="";
-template<>
-const char fullMatrix<float>::parentClassName[]="";
-template<>
-methodBinding *fullMatrix<double>::methods[]={
-  new methodBindingTemplate<const fullMatrix<double>,int>("size1",&fullMatrix<double>::size1),
-  new methodBindingTemplate<const fullMatrix<double>,int>("size2",&fullMatrix<double>::size2),
-  new methodBindingTemplate<const fullMatrix<double>,double,int,int>("get",&fullMatrix<double>::get),
-  new methodBindingTemplate<fullMatrix<double>,void,int,int,double>("set",&fullMatrix<double>::set),
-  new methodBindingTemplate<fullMatrix<double>,void,const fullMatrix<double>*,const fullMatrix<double> *>("gemm",&fullMatrix<double>::gemm),
-  0
-};
-template<>
-constructorBinding *fullMatrix<double>::constructorMethod = new constructorBindingTemplate<fullMatrix<double>,int,int>();
-#endif
-
-
+void fullMatrix<double>::registerBindings(binding *b){
+  classBinding *cb = b->addClass<fullMatrix<double> >("fullMatrix");
+  methodBinding *cm;
+  cb->addMethod("size1",&fullMatrix<double>::size1);
+  cb->addMethod("size2",&fullMatrix<double>::size2);
+  cb->addMethod("get",&fullMatrix<double>::get);
+  cb->addMethod("set",&fullMatrix<double>::set);
+  cb->addMethod("gemm",&fullMatrix<double>::gemm);
+  cb->setConstructor(constructorPtr<fullMatrix<double>,int,int>);
+}
 #endif
diff --git a/Numeric/fullMatrix.h b/Numeric/fullMatrix.h
index 4a3a2c451b4a05317061487d6e15fefe07889a88..9bec79e685025b0be6ed4a2fa929b77ca8e33b54 100644
--- a/Numeric/fullMatrix.h
+++ b/Numeric/fullMatrix.h
@@ -11,6 +11,7 @@
 #include "GmshConfig.h"
 #include "GmshMessage.h"
 
+class binding;
 template <class scalar> class fullMatrix;
 
 template <class scalar>
@@ -93,10 +94,6 @@ class fullVector
     printf("\n");
   }
 };
-#if defined(HAVE_LUA)
-class methodBinding;
-class constructorBinding;
-#endif
 
 template <class scalar>
 class fullMatrix
@@ -112,12 +109,6 @@ class fullMatrix
   inline void set(int r, int c, scalar v){
     (*this)(r,c)=v;
   }
-#if defined(HAVE_LUA)
-  static const char className[];
-  static const char parentClassName[];
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
-#endif // HAVE LUA  
   fullMatrix(scalar *original, int r, int c){
     _r = r;
     _c = c;
@@ -219,9 +210,6 @@ class fullMatrix
   }
 #endif
   ;
-  inline void gemm (const fullMatrix<scalar> *a, const fullMatrix<scalar> *b){
-    gemm(*a,*b);
-  }
   void gemm(const fullMatrix<scalar> &a, const fullMatrix<scalar> &b, 
             scalar alpha=1., scalar beta=1.)
 #if !defined(HAVE_BLAS)
@@ -370,6 +358,7 @@ inline void add(const fullMatrix<scalar> &m, const double &a)
       printf("\n");
     }
   }
+  static void registerBindings(binding *b);
 };
 
 #endif
diff --git a/Solver/TESTCASES/Advection1D.lua b/Solver/TESTCASES/Advection1D.lua
index fb2abf5186f4023214c73a0e56b7e0d634e0b75e..8df7e25056d5180acb96a72e5fdca6112291f35b 100644
--- a/Solver/TESTCASES/Advection1D.lua
+++ b/Solver/TESTCASES/Advection1D.lua
@@ -17,7 +17,7 @@ v:set(2,0,0)
 nu=fullMatrix(1,1);
 nu:set(0,0,0)
 
-law = ConservationLawAdvection(FunctionConstant(v):getName(), '') 
+law = dgConservationLawAdvection(functionConstant(v):getName(), '') 
 --FunctionConstant(nu):getName())
 
 dg:setConservationLaw(law)
@@ -25,7 +25,7 @@ dg:setConservationLaw(law)
 -- boundary condition
 outside=fullMatrix(1,1)
 outside:set(0,0,0.)
-bndcondition=law:newOutsideValueBoundary(FunctionConstant(outside):getName())
+bndcondition=law:newOutsideValueBoundary(functionConstant(outside):getName())
 law:addBoundaryCondition('Left',bndcondition)
 law:addBoundaryCondition('Right',bndcondition)
 
@@ -44,7 +44,7 @@ function initial_condition( xyz , f )
     end	
   end
 end
-dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName())
+dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName())
 
 dg:exportSolution('output/Adv1D_unlimited')
 dg:limitSolution()
diff --git a/Solver/TESTCASES/Advection3D.lua b/Solver/TESTCASES/Advection3D.lua
index 14de45f995fb91c58f892493fd19132f454d8c1c..149f7fbc4b39d8402f4fcdef0f89c2436d189be9 100644
--- a/Solver/TESTCASES/Advection3D.lua
+++ b/Solver/TESTCASES/Advection3D.lua
@@ -15,16 +15,16 @@ v:set(2,0,0)
 nu=fullMatrix(1,1);
 nu:set(0,0,0.001)
 
---law = ConservationLawAdvection(FunctionConstant(v):getName(),FunctionConstant(nu):getName())
---law = ConservationLawAdvection('',FunctionConstant(nu):getName())
-law = ConservationLawAdvection(FunctionConstant(v):getName(),'')
+--law = ConservationLawAdvection(functionConstant(v):getName(),functionConstant(nu):getName())
+--law = ConservationLawAdvection('',functionConstant(nu):getName())
+law = dgConservationLawAdvection(functionConstant(v):getName(),'')
 
 dg:setConservationLaw(law)
 
 -- boundary condition
 outside=fullMatrix(1,1)
 outside:set(0,0,1)
-bndcondition=law:newOutsideValueBoundary(FunctionConstant(outside):getName())
+bndcondition=law:newOutsideValueBoundary(functionConstant(outside):getName())
 --[[law:addBoundaryCondition('Left',bndcondition)
 law:addBoundaryCondition('Right',bndcondition)
 --]]
@@ -41,7 +41,7 @@ function initial_condition( xyz , f )
     f:set (i, 0, x )
   end
 end
--- dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName())
+-- dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName())
 
 law:addBoundaryCondition('boundary',law:new0FluxBoundary())
 
diff --git a/Solver/TESTCASES/AdvectionDiffusion.lua b/Solver/TESTCASES/AdvectionDiffusion.lua
index 3be0149715359c7320b28a4af8f7b8558ced965e..56a34529dc1daa5bc7af4b3cd777006d16dd3c13 100644
--- a/Solver/TESTCASES/AdvectionDiffusion.lua
+++ b/Solver/TESTCASES/AdvectionDiffusion.lua
@@ -10,7 +10,7 @@ vmodel[1]:load('')
 vmodel[2]:load('')
 
 dg = dgSystemOfEquations (model)
-dg:setOrder(1)
+dg:setOrder(3)
 
 -- conservation law
 
@@ -24,13 +24,13 @@ v:set(2,0,0)
 nu=fullMatrix(1,1);
 nu:set(0,0,0.001)
 
-law = ConservationLawAdvection(FunctionConstant(v):getName(),FunctionConstant(nu):getName())
+law = dgConservationLawAdvection(functionConstant(v):getName(),functionConstant(nu):getName())
 dg:setConservationLaw(law)
 
 -- boundary condition
 outside=fullMatrix(1,1)
 outside:set(0,0,0.)
-law:addBoundaryCondition('Border',law:newOutsideValueBoundary(FunctionConstant(outside):getName()))
+law:addBoundaryCondition('Border',law:newOutsideValueBoundary(functionConstant(outside):getName()))
 
 dg:setup()
 
@@ -43,14 +43,14 @@ function initial_condition( xyz , f )
     f:set (i, 0, math.exp(-100*((x-0.2)^2 +(y-0.3)^2)))
   end
 end
-dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName())
+dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName())
 
 dg:exportSolution('output/Advection_00000')
 
 -- main loop
 for i=1,10000 do
   norm = dg:RK44(0.01)
-  if (i % 1 == 0) then 
+  if (i % 10 == 0) then 
     print('iter',i,norm)
     dg:exportSolution(string.format("output/Advection-%05d", i)) 
   end
diff --git a/Solver/TESTCASES/Diffusion.lua b/Solver/TESTCASES/Diffusion.lua
index 4b969dc01e2a50ea87dc33a0363c98c17660fd37..b8093035934f6b9b44b08ab2bc77f13ffefe114b 100644
--- a/Solver/TESTCASES/Diffusion.lua
+++ b/Solver/TESTCASES/Diffusion.lua
@@ -2,14 +2,14 @@ model = GModel  ()
 model:load ('square.geo')
 model:load ('square.msh')
 dg = dgSystemOfEquations (model)
-dg:setOrder(5)
+dg:setOrder(3)
 
 
 -- conservation law
 -- advection speed
 nu=fullMatrix(1,1);
 nu:set(0,0,0.01)
-law = ConservationLawAdvection('',FunctionConstant(nu):getName())
+law = dgConservationLawAdvection('',functionConstant(nu):getName())
 dg:setConservationLaw(law)
 
 -- boundary condition
@@ -28,7 +28,7 @@ function initial_condition( xyz , f )
     f:set (i, 0, math.exp(-100*((x-0.2)^2 +(y-0.3)^2)))
   end
 end
-dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName())
+dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName())
 
 dg:exportSolution('output/Diffusion_00000')
 
diff --git a/Solver/TESTCASES/ForwardFacingStep.lua b/Solver/TESTCASES/ForwardFacingStep.lua
index e474376ad9a10315e642d7f881350281120834c0..2c4ccff29aeabd9c746d0f1ae3c98f4bf3901f5b 100644
--- a/Solver/TESTCASES/ForwardFacingStep.lua
+++ b/Solver/TESTCASES/ForwardFacingStep.lua
@@ -28,11 +28,11 @@ myModel:load ('step.msh')
 print'*** Create a dg solver ***'
 DG = dgSystemOfEquations (myModel)
 DG:setOrder(order)
-law=ConservationLawPerfectGas2d()
+law=dgPerfectGasLaw2d()
 DG:setConservationLaw(law)
 law:addBoundaryCondition('Walls',law:newWallBoundary())
 
-FS = FunctionLua(4, 'free_stream', {'XYZ'}):getName()
+FS = functionLua(4, 'free_stream', {'XYZ'}):getName()
 
 law:addBoundaryCondition('LeftRight',law:newOutsideValueBoundary(FS))
 DG:setup()
diff --git a/Solver/TESTCASES/Stommel.lua b/Solver/TESTCASES/Stommel.lua
index b5017e97c941d5cf8703f8efab0df1fdf243cea9..b7b1ef93c754c32a754cafa9c7f5f128b02c0b67 100644
--- a/Solver/TESTCASES/Stommel.lua
+++ b/Solver/TESTCASES/Stommel.lua
@@ -3,8 +3,8 @@ model:load ('stommel_square.msh')
 dg = dgSystemOfEquations (model)
 order=1
 dg:setOrder (order)
-claw = ShallowWater2d()
-claw:addBoundaryCondition('Wall',claw:newWallBoundary())
+claw = dgConservationLawShallowWater2d()
+claw:addBoundaryCondition('Wall',claw:newBoundaryWall())
 dg:setConservationLaw(claw)
 dg:setup()
 
diff --git a/Solver/TESTCASES/WavePulse.lua b/Solver/TESTCASES/WavePulse.lua
index a9251261f9846e87d706631612ae3d440b19f9d0..982cfeb34db6ac4300a7e8dc7876a6a59ef67708 100644
--- a/Solver/TESTCASES/WavePulse.lua
+++ b/Solver/TESTCASES/WavePulse.lua
@@ -27,15 +27,16 @@ myModel   = GModel  ()
 --myModel:load('square_quads.msh')
 myModel:load('square_mixed.msh')
 
+
 print'*** Create a dg solver ***'
 DG = dgSystemOfEquations (myModel)
-DG:setOrder(2)
-law=ConservationLawWaveEquation(2)
+DG:setOrder(3)
+law=dgConservationLawWaveEquation(2)
 DG:setConservationLaw(law)
-law:addBoundaryCondition('Border',law:newWallBoundary())
+law:addBoundaryCondition('Border',law:newBoundaryWall())
 DG:setup()
 
-initialCondition = FunctionLua(3,'initial_condition',{'XYZ'}):getName()
+initialCondition = functionLua(3,'initial_condition',{'XYZ'}):getName()
 
 print'*** setting the initial solution ***'
 
@@ -55,7 +56,7 @@ for i=1,N do
 --    norm = DG:multirateRK43(dt)
     norm = DG:RK44(dt)
     print('*** ITER ***',i,norm)
-    if (i % 100 == 0) then 
+    if (i % 10 == 0) then 
        DG:exportSolution(string.format("output/solution-%04d", i)) 
     end
 end
diff --git a/Solver/TESTCASES/square_mixed.geo b/Solver/TESTCASES/square_mixed.geo
index 267a1bd2df059225386757395d917c745cc0539c..bfc7da2a66518f15fe09658bfed76d08e7983712 100644
--- a/Solver/TESTCASES/square_mixed.geo
+++ b/Solver/TESTCASES/square_mixed.geo
@@ -1,4 +1,4 @@
-N=25;
+N=5;
 Point(1) = {0.0, 0.0, 0, .03};
 Point(2) = {1, 0.0, 0, .03};
 Point(3) = {1, 1, 0, .03};
diff --git a/Solver/dgConservationLaw.cpp b/Solver/dgConservationLaw.cpp
index f1e8cd05def2f64a22f0f373eb95ac6ce3c8e0eb..fce315c2a3bb54fee79db05a086491a81e71b453 100644
--- a/Solver/dgConservationLaw.cpp
+++ b/Solver/dgConservationLaw.cpp
@@ -63,15 +63,16 @@ dgBoundaryCondition *dgConservationLaw::new0FluxBoundary() {
 }
 
 #include "Bindings.h"
-const char dgConservationLaw::className[]="ConservationLaw";
-const char  dgConservationLaw::parentClassName[]="";
-methodBinding * dgConservationLaw::methods[]={
-  new methodBindingTemplate<dgConservationLaw,void,std::string,dgBoundaryCondition*>("addBoundaryCondition",&dgConservationLaw::addBoundaryCondition),
-  new methodBindingTemplate<dgConservationLaw,dgBoundaryCondition*>("new0FluxBoundary",&dgConservationLaw::new0FluxBoundary),
-  new methodBindingTemplate<dgConservationLaw,dgBoundaryCondition*,std::string>("newOutsideValueBoundary",&dgConservationLaw::newOutsideValueBoundary),
-0};
-constructorBinding * dgConservationLaw::constructorMethod=NULL;
-const char dgBoundaryCondition::className[]="BoundaryCondition";
-const char  dgBoundaryCondition::parentClassName[]="";
-methodBinding * dgBoundaryCondition::methods[]={0};
-constructorBinding * dgBoundaryCondition::constructorMethod=NULL;
+
+void dgConservationLaw::registerBindings(binding *b){
+  classBinding *cb = b->addClass<dgConservationLaw>("dgConservationLaw");
+  cb->addMethod("addBoundaryCondition",&dgConservationLaw::addBoundaryCondition);
+  cb->addMethod("new0FluxBoundary",&dgConservationLaw::new0FluxBoundary);
+  cb->addMethod("newOutsideValueBoundary",&dgConservationLaw::newOutsideValueBoundary);
+}
+
+
+
+void dgBoundaryCondition::registerBindings(binding *b){
+  classBinding *cb = b->addClass<dgBoundaryCondition>("dgBoundaryCondition");
+}
diff --git a/Solver/dgConservationLaw.h b/Solver/dgConservationLaw.h
index 7e037cd3e1312ce9f8d4bcf2e371438d070b8d0f..6a4460a637fd105f470da4842085a5f1823e7add 100644
--- a/Solver/dgConservationLaw.h
+++ b/Solver/dgConservationLaw.h
@@ -9,19 +9,15 @@
 #include "fullMatrix.h"
 class dataCacheDouble;
 class dataCacheMap;
-class constructorBinding;
-class methodBinding;
 
 class dgConservationLaw;
+class binding;
 
 class dgBoundaryCondition {
  public:
   virtual ~dgBoundaryCondition () {}
   virtual dataCacheDouble *newBoundaryTerm(dataCacheMap &cacheMapLeft) const = 0;
-  static const char className[];
-  static const char parentClassName[];
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
+  static void registerBindings(binding *b);
 };
 
 class dgConservationLaw {
@@ -58,10 +54,7 @@ class dgConservationLaw {
   dgBoundaryCondition *newOutsideValueBoundary(std::string outsideValueFunctionName);
   dgBoundaryCondition *new0FluxBoundary();
 
-  static const char className[];
-  static const char parentClassName[];
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
+  static void registerBindings(binding *b);
 };
 
 dgConservationLaw *dgNewPerfectGasLaw2d();
diff --git a/Solver/dgConservationLawAdvection.cpp b/Solver/dgConservationLawAdvection.cpp
index a97805fca2510274a6412bce64eff5d821bcc30b..a8b02efa194eee511ade39d087a60ab745004027 100644
--- a/Solver/dgConservationLawAdvection.cpp
+++ b/Solver/dgConservationLawAdvection.cpp
@@ -94,8 +94,9 @@ dgConservationLawAdvection::dgConservationLawAdvection(std::string vFunctionName
 }
 
 #include "Bindings.h"
-const char * dgConservationLawAdvection::className = "ConservationLawAdvection";
-const char * dgConservationLawAdvection::parentClassName = "ConservationLaw";
-constructorBinding *dgConservationLawAdvection::constructorMethod = new constructorBindingTemplate<dgConservationLawAdvection,std::string,std::string>();
-methodBinding *dgConservationLawAdvection::methods []={0};
 
+void dgConservationLawAdvectionRegisterBindings (binding *b){
+  classBinding *cb = b->addClass<dgConservationLawAdvection>("dgConservationLawAdvection");
+  cb->setConstructor(constructorPtr<dgConservationLawAdvection,std::string,std::string>);
+  cb->setParentClass<dgConservationLaw>();
+}
diff --git a/Solver/dgConservationLawAdvection.h b/Solver/dgConservationLawAdvection.h
index 69c11578a2bb322280158e1ed91a1326a3ea47d5..f56894bb21ca4e7348df329a6bfd7b0c7d2fbcb7 100644
--- a/Solver/dgConservationLawAdvection.h
+++ b/Solver/dgConservationLawAdvection.h
@@ -1,8 +1,6 @@
 #ifndef _DG_CONSERVATION_LAW_ADVECTION_H
 #define _DG_CONSERVATION_LAW_ADVECTION_H
 #include "dgConservationLaw.h"
-class constructorBinding;
-class methodBinding;
 class dgConservationLawAdvection : public dgConservationLaw {
   std::string _vFunctionName,_nuFunctionName;
   class advection;
@@ -14,9 +12,7 @@ class dgConservationLawAdvection : public dgConservationLaw {
   dataCacheDouble *newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const;
   dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const;
   dgConservationLawAdvection(std::string vFunctionName, std::string nuFunctionName);
-  static const char * className;
-  static const char * parentClassName;
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
 };
+class binding;
+void dgConservationLawAdvectionRegisterBindings (binding *b);
 #endif
diff --git a/Solver/dgConservationLawPerfectGas.cpp b/Solver/dgConservationLawPerfectGas.cpp
index 4776a51719042691995e5fe9b4e433a5e398055d..5a21432eea53711356582724ff11e1b57aaf9ef0 100644
--- a/Solver/dgConservationLawPerfectGas.cpp
+++ b/Solver/dgConservationLawPerfectGas.cpp
@@ -311,10 +311,11 @@ class dgBoundaryConditionPerfectGasLaw2dFreeStream : public dgBoundaryCondition
 #endif
 
 #include "Bindings.h"
-const char *dgPerfectGasLaw2d::className = "ConservationLawPerfectGas2d";
-const char *dgPerfectGasLaw2d::parentClassName = "ConservationLaw";
-methodBinding *dgPerfectGasLaw2d::methods[] ={
-  new methodBindingTemplate<const dgPerfectGasLaw2d,dgBoundaryCondition*>("newWallBoundary",&dgPerfectGasLaw2d::newWallBoundary),
-0};
-constructorBinding *dgPerfectGasLaw2d::constructorMethod=new constructorBindingTemplate<dgPerfectGasLaw2d>();
 
+void dgPerfectGasLaw2dRegisterBindings (binding *b){
+  classBinding *cb = b->addClass<dgPerfectGasLaw2d>("dgPerfectGasLaw2d");
+  methodBinding *cm;
+  cb->addMethod("newWallBoundary",&dgPerfectGasLaw2d::newWallBoundary);
+  cb->setConstructor(constructorPtr<dgPerfectGasLaw2d>);
+  cb->setParentClass<dgConservationLaw>();
+}
diff --git a/Solver/dgConservationLawPerfectGas.h b/Solver/dgConservationLawPerfectGas.h
index 434e9e602a51a2adf66ea016798b1d4ff2651539..c53ff8c057d001a3b642873c3d5ad7f8bd402e2d 100644
--- a/Solver/dgConservationLawPerfectGas.h
+++ b/Solver/dgConservationLawPerfectGas.h
@@ -11,10 +11,8 @@ class dgPerfectGasLaw2d : public dgConservationLaw {
   dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const;
   dataCacheDouble *newSourceTerm (dataCacheMap &cacheMap) const;
   dgPerfectGasLaw2d();
-  static const char * className;
-  static const char * parentClassName;
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
   dgBoundaryCondition *newWallBoundary()const ;
 };
+class binding;
+void dgPerfectGasLaw2dRegisterBindings(binding *b);
 #endif
diff --git a/Solver/dgConservationLawShallowWater2d.cpp b/Solver/dgConservationLawShallowWater2d.cpp
index 76ddc2f910b0c58d65417cbb44a546e926e63f83..de798d27b071ebb489974f9c1352e721a174dbc3 100644
--- a/Solver/dgConservationLawShallowWater2d.cpp
+++ b/Solver/dgConservationLawShallowWater2d.cpp
@@ -140,13 +140,11 @@ dgBoundaryCondition *dgConservationLawShallowWater2d::newBoundaryWall(){
   return new boundaryWall();
 }
 
-#ifdef HAVE_LUA
 #include "Bindings.h"
-const char dgConservationLawShallowWater2d::className[]="ShallowWater2d";
-const char dgConservationLawShallowWater2d::parentClassName[]="ConservationLaw";
-methodBinding *dgConservationLawShallowWater2d::methods[]={
-  new methodBindingTemplate<dgConservationLawShallowWater2d,dgBoundaryCondition*>("newWallBoundary",&dgConservationLawShallowWater2d::newBoundaryWall),
-  0
-};
-constructorBinding *dgConservationLawShallowWater2d::constructorMethod=new constructorBindingTemplate<dgConservationLawShallowWater2d>();
-#endif
+void dgConservationLawShallowWater2dRegisterBindings (binding *b){
+  classBinding *cb = b->addClass<dgConservationLawShallowWater2d>("dgConservationLawShallowWater2d");
+  methodBinding *cm;
+  cb->addMethod("newBoundaryWall",&dgConservationLawShallowWater2d::newBoundaryWall);
+  cb->setConstructor(constructorPtr<dgConservationLawShallowWater2d>);
+  cb->setParentClass<dgConservationLaw>();
+}
diff --git a/Solver/dgConservationLawShallowWater2d.h b/Solver/dgConservationLawShallowWater2d.h
index c37c9525e2320800933ebaa75bf6ea491a3d8a89..2cf268972b24657e820c4b64806178fd97320843 100644
--- a/Solver/dgConservationLawShallowWater2d.h
+++ b/Solver/dgConservationLawShallowWater2d.h
@@ -2,11 +2,8 @@
 #define _DG_CONSERVATION_LAW_SHALLOW_WATER_2D_
 #include "dgConservationLaw.h"
 
-#ifdef HAVE_LUA
-class methodBinding;
-class constructorBinding;
-#endif
 class dataCacheMap;
+class binding;
 
 class dgConservationLawShallowWater2d : public dgConservationLaw {
   class advection;
@@ -23,11 +20,6 @@ class dgConservationLawShallowWater2d : public dgConservationLaw {
     _nbf = 3; // H U(=Hu) V(=Hv)
   }
   dgBoundaryCondition *newBoundaryWall();
-#ifdef HAVE_LUA
-  static const char className[];
-  static const char parentClassName[];
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
-#endif
 };
+void dgConservationLawShallowWater2dRegisterBindings(binding *b);
 #endif
diff --git a/Solver/dgConservationLawWaveEquation.cpp b/Solver/dgConservationLawWaveEquation.cpp
index 9d9e18ef7247aa99aa4fbb6dad67b8039760375c..583b79c7e0c818c5d4a877c3ebbe35de48b4d97e 100644
--- a/Solver/dgConservationLawWaveEquation.cpp
+++ b/Solver/dgConservationLawWaveEquation.cpp
@@ -136,9 +136,10 @@ dgBoundaryCondition *dgConservationLawWaveEquation::newBoundaryWall()const{
 }
 
 #include "Bindings.h"
-const char *dgConservationLawWaveEquation::className = "ConservationLawWaveEquation";
-const char *dgConservationLawWaveEquation::parentClassName = "ConservationLaw";
-methodBinding *dgConservationLawWaveEquation::methods[] ={
-  new methodBindingTemplate<const dgConservationLawWaveEquation,dgBoundaryCondition*>("newWallBoundary",&dgConservationLawWaveEquation::newBoundaryWall),
-0};
-constructorBinding *dgConservationLawWaveEquation::constructorMethod=new constructorBindingTemplate<dgConservationLawWaveEquation,int>();
+void dgConservationLawWaveEquationRegisterBindings(binding *b){
+  classBinding *cb = b->addClass<dgConservationLawWaveEquation> ("dgConservationLawWaveEquation");
+  methodBinding *cm;
+  cb->addMethod("newBoundaryWall",&dgConservationLawWaveEquation::newBoundaryWall);
+  cb->setConstructor(constructorPtr<dgConservationLawWaveEquation,int>);
+  cb->setParentClass<dgConservationLaw>();
+}
diff --git a/Solver/dgConservationLawWaveEquation.h b/Solver/dgConservationLawWaveEquation.h
index 530dff8b2d080b4f57c9e57f766fa4e06e16ded4..ee3498acdd00ded72aecc1712a91e7c0b7c2ab38 100644
--- a/Solver/dgConservationLawWaveEquation.h
+++ b/Solver/dgConservationLawWaveEquation.h
@@ -21,4 +21,5 @@ class dgConservationLawWaveEquation : public dgConservationLaw {
   static methodBinding *methods[];
   static constructorBinding *constructorMethod;
 };
+void dgConservationLawWaveEquationRegisterBindings(binding *b);
 #endif
diff --git a/Solver/dgSystemOfEquations.cpp b/Solver/dgSystemOfEquations.cpp
index b514d7a0e882e443be6a85b623e185d35b7ba662..df6070965a80fa91c27cde15c6943a0e21960f49 100644
--- a/Solver/dgSystemOfEquations.cpp
+++ b/Solver/dgSystemOfEquations.cpp
@@ -37,24 +37,34 @@ void dgSystemOfEquations::setConservationLaw (dgConservationLaw *law){
   _claw=law;
 }
 
-#ifdef HAVE_LUA
 #include "Bindings.h"
-const char dgSystemOfEquations::className[] = "dgSystemOfEquations";
-const char dgSystemOfEquations::parentClassName[] = "";
-constructorBinding *dgSystemOfEquations::constructorMethod = new constructorBindingTemplate<dgSystemOfEquations,GModel*>();
-methodBinding *dgSystemOfEquations::methods[]={
-  new methodBindingTemplate<dgSystemOfEquations,void,int>("setOrder",&dgSystemOfEquations::setOrder),
-  new methodBindingTemplate<dgSystemOfEquations,void,dgConservationLaw*>("setConservationLaw",&dgSystemOfEquations::setConservationLaw),
-  new methodBindingTemplate<dgSystemOfEquations,void>("setup",&dgSystemOfEquations::setup),
-  new methodBindingTemplate<dgSystemOfEquations,void,std::string>("exportSolution",&dgSystemOfEquations::exportSolution),
-  new methodBindingTemplate<dgSystemOfEquations,void>("limitSolution",&dgSystemOfEquations::limitSolution),
-  new methodBindingTemplate<dgSystemOfEquations,void,std::string>("L2Projection",&dgSystemOfEquations::L2Projection),
-  new methodBindingTemplate<dgSystemOfEquations,double,double>("RK44",&dgSystemOfEquations::RK44),
-  new methodBindingTemplate<dgSystemOfEquations,double>("computeInvSpectralRadius",&dgSystemOfEquations::computeInvSpectralRadius),
-  new methodBindingTemplate<dgSystemOfEquations,double,double>("RK44_limiter",&dgSystemOfEquations::RK44_limiter),
-  new methodBindingTemplate<dgSystemOfEquations,double,double>("multirateRK43",&dgSystemOfEquations::multirateRK43),
- 0};
-#endif // HAVE_LUA
+void dgSystemOfEquations::registerBindings(binding *b){
+  classBinding *cb = b->addClass<dgSystemOfEquations>("dgSystemOfEquations");
+  cb->setDescription("a class to rule them all :-) -- bad description, this class will be removed anyway");
+  cb->setConstructor(constructorPtr<dgSystemOfEquations,GModel*>);
+  methodBinding *cm;
+  cm = cb->addMethod("setConservationLaw",&dgSystemOfEquations::setConservationLaw);
+  cm->setArgNames("law",NULL);
+  cm->setDescription("set the conservation law this system solve");
+  cm = cb->addMethod("setup",&dgSystemOfEquations::setup);
+  cm->setDescription("allocate and init internal stuff, call this function after setOrder and setLaw and before anything else on this instance");
+  cm = cb->addMethod("exportSolution",&dgSystemOfEquations::exportSolution);
+  cm->setArgNames("filename",NULL);
+  cm->setDescription("Print the solution into a file. This file does not contain the mesh. To visualize the solution in gmsh you have to open the mesh file first.");
+  cm= cb->addMethod("L2Projection",&dgSystemOfEquations::L2Projection);
+  cm->setArgNames("functionName",NULL);
+  cm->setDescription("project the function \"functionName\" on the solution vector");
+  cm = cb->addMethod("RK44",&dgSystemOfEquations::RK44);
+  cm->setArgNames("norm","dt",NULL);
+  cm->setDescription("do a runge-kuta temporal iteration with a time step \"dt\" and return the sum of the nodal residuals");
+  cm = cb->addMethod("setOrder",&dgSystemOfEquations::setOrder);
+  cm->setArgNames("order",NULL);
+  cm->setDescription("set the polynpolynomialomial order of the lagrange shape functions");
+  cb->addMethod("limitSolution",&dgSystemOfEquations::limitSolution);
+  cb->addMethod("computeInvSpectralRadius",&dgSystemOfEquations::computeInvSpectralRadius);
+  cb->addMethod("RK44_limiter",&dgSystemOfEquations::RK44_limiter);
+  cb->addMethod("multirateRK43",&dgSystemOfEquations::multirateRK43);
+}
 
 // do a L2 projection
 void dgSystemOfEquations::L2Projection (std::string functionName){
diff --git a/Solver/dgSystemOfEquations.h b/Solver/dgSystemOfEquations.h
index 32aa5d8c2e57f3ae292e8324f936d16894f55001..edc36dddf71bafa1f5ede84d035e2e6c01800939 100644
--- a/Solver/dgSystemOfEquations.h
+++ b/Solver/dgSystemOfEquations.h
@@ -26,8 +26,7 @@ public:
   int getNbFields() {return nbFields;}
 };
 
-class methodBinding;
-class constructorBinding;
+class binding;
 
 class dgSystemOfEquations {
   // the mesh and the model
@@ -65,10 +64,7 @@ public:
   void L2Projection (std::string functionName); // assign the solution to a given function
   double computeInvSpectralRadius();
 
-  static const char className[];
-  static const char parentClassName[];
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
+  static void registerBindings(binding *b);
 
   inline const fullMatrix<double> getSolutionProxy (int iGroup, int iElement){
     return fullMatrix<double> ( *_solution->_dataProxys [iGroup] ,
diff --git a/Solver/function.cpp b/Solver/function.cpp
index f092620340b91f1859f14dab80308ae105f54522..209fddc2a26c02632d15a9d965478d334a920f09 100644
--- a/Solver/function.cpp
+++ b/Solver/function.cpp
@@ -141,23 +141,17 @@ functionConstant::functionConstant(const fullMatrix<double> *source){
 }
 
 #include "Bindings.h"
-const char *functionConstant::className="FunctionConstant";
-const char *functionConstant::parentClassName="Function";
-methodBinding *functionConstant::methods[]={0};
-constructorBinding *functionConstant::constructorMethod=new constructorBindingTemplate<functionConstant,fullMatrix<double>*>();
-
-
-
-
 
 void function::registerDefaultFunctions()
 {
   function::add("XYZ", new functionXYZ);
 }
 
-const char *function::className="Function";
-const char *function::parentClassName="";
-methodBinding *function::methods[]={new methodBindingTemplate<const function,std::string>("getName",&function::getName),
-0};
-constructorBinding *function::constructorMethod=0;
+void function::registerBindings(binding *b){
+  classBinding *cb = b->addClass<function>("function");
+  cb->addMethod("getName",&function::getName);
+  cb = b->addClass<functionConstant>("functionConstant");
+  cb->setConstructor(constructorPtr<functionConstant,fullMatrix<double>*>);
+  cb->setParentClass<function>();
+}
 
diff --git a/Solver/function.h b/Solver/function.h
index 88b6fe5fb64e33d043be662b409f9f5bebcc7eea..bc8bdc5c4a41479fc6412763e9cc974999d00383 100644
--- a/Solver/function.h
+++ b/Solver/function.h
@@ -7,8 +7,7 @@
 #include <fullMatrix.h>
 class dataCacheMap;
 class MElement;
-class methodBinding;
-class constructorBinding;
+class binding;
 
 // those classes manage complex function dependencies and keep their values in cache so that they are not recomputed when it is not necessary. To do this, we use three classes : function, dataCache and dataCacheMap. The workflow is :
 //
@@ -127,11 +126,8 @@ class function {
 
   inline  std::string getName()const {return _name;}
 
-  static const char *className;
-  static const char *parentClassName;
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
   virtual ~function(){};
+  static void registerBindings(binding *b);
 };
 
 // A special node in the dependency tree for which all the leafs
@@ -179,12 +175,5 @@ class functionConstant : public function {
   fullMatrix<double> _source;
   dataCacheDouble *newDataCache(dataCacheMap *m);
   functionConstant(const fullMatrix<double> *source);
-  static const char *className;
-  static const char *parentClassName;
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
-  ~functionConstant(){
-    printf("delete fc\n");
-  }
 };
 #endif
diff --git a/Solver/luaFunction.cpp b/Solver/luaFunction.cpp
index 4e7083cfd5f23391bfc0a16f6417045ec20b9260..832ddded3f3ef713c83b3dd4de480b224ee3b7c3 100644
--- a/Solver/luaFunction.cpp
+++ b/Solver/luaFunction.cpp
@@ -26,9 +26,9 @@ class functionLua::data : public dataCacheDouble{
     lua_getfield(_function->_L, LUA_GLOBALSINDEX, _function->_luaFunctionName.c_str());
     for (int i=0;i< _dependencies.size();i++){
       const fullMatrix<double> *data = &(*_dependencies[i])();
-      classBinding<const fullMatrix<double> >::push(_function->_L,data,false);
+      luaStack<const fullMatrix<double>*>::push(_function->_L,data);
     }
-    classBinding<const fullMatrix<double> >::push(_function->_L,&_value,false);
+    luaStack<const fullMatrix<double>*>::push(_function->_L,&_value);
     lua_call(_function->_L,_dependencies.size()+1,0);  /* call Lua function */
   }
 };
@@ -46,9 +46,10 @@ dataCacheDouble *functionLua::newDataCache(dataCacheMap *m)
   return new data(this,m);
 }
 
-const char *functionLua::className="FunctionLua";
-const char *functionLua::parentClassName="Function";
-methodBinding *functionLua::methods[]={0};
-constructorBinding *functionLua::constructorMethod=new constructorBindingTemplate<functionLua,int,std::string,std::vector<std::string> ,lua_State*>();
+void functionLua::registerBindings(binding *b){
+  classBinding *cb= b->addClass<functionLua>("functionLua");
+  cb->setConstructor(constructorPtr<functionLua,int,std::string,std::vector<std::string>,lua_State*>);
+  cb->setParentClass<function>();
+}
 
 #endif // HAVE LUA
diff --git a/Solver/luaFunction.h b/Solver/luaFunction.h
index 63e66c937e420ccaf2f229bb854404788d42a68a..2ded4ce76d655b820ba84692eeb3861f2e43329a 100644
--- a/Solver/luaFunction.h
+++ b/Solver/luaFunction.h
@@ -6,6 +6,7 @@
 class lua_State;
 #include <string>
 #include <vector>
+class binding;
 class functionLua : public function {
   lua_State *_L;
   std::string _luaFunctionName;
@@ -16,10 +17,7 @@ class functionLua : public function {
   functionLua (int nbCol, std::string &luaFunctionName, std::vector<std::string> &dependenciesName, lua_State *L);
 
   dataCacheDouble *newDataCache(dataCacheMap *m);
-  static const char *className;
-  static const char *parentClassName;
-  static methodBinding *methods[];
-  static constructorBinding *constructorMethod;
+  static void registerBindings(binding *b);
 };
 #endif // HAVE LUA
 #endif // _LUA_FUNCTION_H_