Index: code/branches/pch/src/tolua/CMakeLists.txt
===================================================================
--- code/branches/pch/src/tolua/CMakeLists.txt	(revision 3126)
+++ code/branches/pch/src/tolua/CMakeLists.txt	(revision 3127)
@@ -54,5 +54,5 @@
   ORXONOX_EXTERNAL
   VERSION
-    1.0.92
+    1.0.93
   LINK_LIBRARIES
     ${LUA_LIBRARIES}
@@ -88,4 +88,5 @@
   ${CMAKE_CURRENT_SOURCE_DIR}/lua/class.lua
   ${CMAKE_CURRENT_SOURCE_DIR}/lua/clean.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/template_class.lua
   ${CMAKE_CURRENT_SOURCE_DIR}/lua/doit.lua
 
Index: code/branches/pch/src/tolua/README
===================================================================
--- code/branches/pch/src/tolua/README	(revision 3126)
+++ code/branches/pch/src/tolua/README	(revision 3127)
@@ -14,12 +14,10 @@
 
 * Availability
-  tolua is freely available; you can redistribute it and/or modify it.
-  The software provided hereunder is on an "as is" basis, and
-  the author has no obligation to provide maintenance, support, 
-  updates, enhancements, or modifications.
 
-  tolua can be downloaded from the sites below:
+  tolua++ is freely available for both academic and commercial purposes.
+  See COPYRIGHT for details.
+
+  tolua++ can be downloaded from the sites below:
             http://www.codenix.com/~tolua/
-            http://www.codenix.com/~tolua/tolua++-1.0.tar.bz2
 
 * Installation
Index: code/branches/pch/src/tolua/VERSION
===================================================================
--- code/branches/pch/src/tolua/VERSION	(revision 3126)
+++ code/branches/pch/src/tolua/VERSION	(revision 3127)
@@ -1,3 +1,3 @@
-Tolua++ v1.0.92 with changes:
+Tolua++ v1.0.93 with changes:
 
 - Exception handling by CEGUI team
Index: code/branches/pch/src/tolua/all-5.0.lua
===================================================================
--- code/branches/pch/src/tolua/all-5.0.lua	(revision 3126)
+++ code/branches/pch/src/tolua/all-5.0.lua	(revision 3127)
@@ -18,4 +18,5 @@
 dofile(path.."lua/class.lua")
 dofile(path.."lua/clean.lua")
+dofile(path.."lua/template_class.lua")
 --dofile(path.."lua/custom.lua")
 dofile(path.."lua/doit.lua")
Index: code/branches/pch/src/tolua/all-5.1.lua
===================================================================
--- code/branches/pch/src/tolua/all-5.1.lua	(revision 3126)
+++ code/branches/pch/src/tolua/all-5.1.lua	(revision 3127)
@@ -19,4 +19,5 @@
 dofile(path.."lua/class.lua")
 dofile(path.."lua/clean.lua")
+dofile(path.."lua/template_class.lua")
 --dofile(path.."lua/custom.lua")
 dofile(path.."lua/doit.lua")
Index: code/branches/pch/src/tolua/changes_orxonox.diff
===================================================================
--- code/branches/pch/src/tolua/changes_orxonox.diff	(revision 3126)
+++ code/branches/pch/src/tolua/changes_orxonox.diff	(revision 3127)
@@ -1,5 +1,4 @@
-diff -ruN tolua/tolua++.h tolua2/tolua++.h
---- tolua/tolua++.h	Wed Jan 28 21:51:38 2009
-+++ tolua2/tolua++.h	Sat Jan 10 14:48:44 2009
+--- tolua++.h	Tue Jun  9 16:27:17 2009
++++ tolua++.h	Tue Jun  9 14:50:04 2009
 @@ -16,9 +16,34 @@
  #ifndef TOLUA_H
@@ -37,7 +36,6 @@
  #define TOLUA_VERSION "tolua++-1.0.92"
  
-diff -ruN tolua/tolua.c tolua2/tolua.c
---- tolua/tolua.c	Wed Jan 28 21:51:00 2009
-+++ tolua2/tolua.c	Sat Jan 10 14:48:45 2009
+--- tolua.c	Tue Jun  9 16:27:12 2009
++++ tolua.c	Tue Jun  9 14:50:04 2009
 @@ -4,6 +4,8 @@
  ** TeCGraf/PUC-Rio
@@ -58,5 +56,5 @@
           "  -P       : parse and print structure information (for debug).\n"
           "  -S       : disable support for c++ strings.\n"
-@@ -64,12 +68,12 @@
+@@ -65,12 +69,12 @@
  }
  
@@ -77,5 +75,5 @@
  
  static void error (char* o)
-@@ -81,6 +85,9 @@
+@@ -82,6 +86,9 @@
  
  int main (int argc, char* argv[])
@@ -87,5 +85,5 @@
   lua_State* L = luaL_newstate();
   luaL_openlibs(L);
-@@ -97,6 +104,7 @@
+@@ -98,6 +105,7 @@
   lua_pushstring(L,TOLUA_VERSION); lua_setglobal(L,"TOLUA_VERSION");
   lua_pushstring(L,LUA_VERSION); lua_setglobal(L,"TOLUA_LUA_VERSION");
@@ -95,5 +93,5 @@
   {
    help();
-@@ -124,6 +132,14 @@
+@@ -125,6 +133,14 @@
       case 'o': setfield(L,t,"o",argv[++i]); break;
       case 'n': setfield(L,t,"n",argv[++i]); break;
@@ -110,5 +108,5 @@
       case '1': setfield(L,t,"1",""); break;
       case 'L': setfield(L,t,"L",argv[++i]); break;
-@@ -143,25 +159,53 @@
+@@ -145,25 +161,53 @@
    }
    lua_pop(L,1);
Index: code/branches/pch/src/tolua/lua/array.lua
===================================================================
--- code/branches/pch/src/tolua/lua/array.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/array.lua	(revision 3127)
@@ -102,4 +102,5 @@
     -- return value
     local t,ct = isbasic(self.type)
+    local push_func = get_push_function(t)
     if t then
         output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
@@ -107,7 +108,7 @@
         t = self.type
         if self.ptr == '&' or self.ptr == '' then
-            output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");')
-        else
-            output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");')
+            output(' ',push_func,'(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");')
+        else
+            output(' ',push_func,'(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");')
         end
     end
@@ -193,5 +194,6 @@
             output('tolua_to'..t,'(tolua_S,3,',def,'));')
         else
-            output('tolua_tousertype(tolua_S,3,',def,'));')
+            local to_func = get_to_function(self.type)
+            output(to_func,'(tolua_S,3,',def,'));')
         end
         output(' return 0;')
@@ -203,4 +205,8 @@
 
 function classArray:register (pre)
+    if not self:check_public_access() then
+        return
+    end
+
     pre = pre or ''
     if self.csetname then
Index: code/branches/pch/src/tolua/lua/basic.lua
===================================================================
--- code/branches/pch/src/tolua/lua/basic.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/basic.lua	(revision 3127)
@@ -112,4 +112,7 @@
 
 function warning (msg)
+    if flags.q then
+        return
+    end
     local out = _OUTPUT
     _OUTPUT = _STDERR
@@ -333,4 +336,8 @@
 end
 
+-- called before starting output
+function pre_output_hook(package)
+
+end
 
 -- called after writing all the output.
@@ -354,3 +361,56 @@
 end
 
-
+-- called from classFunction:supcode, before the call to the function is output
+function pre_call_hook(f)
+
+end
+
+-- called from classFunction:supcode, after the call to the function is output
+function post_call_hook(f)
+
+end
+
+-- called before the register code is output
+function pre_register_hook(package)
+
+end
+
+-- called to output an error message
+function output_error_hook(...)
+    return string.format(...)
+end
+
+-- custom pushers
+
+_push_functions = {}
+_is_functions = {}
+_to_functions = {}
+
+_base_push_functions = {}
+_base_is_functions = {}
+_base_to_functions = {}
+
+local function search_base(t, funcs)
+    local class = _global_classes[t]
+
+    while class do
+        if funcs[class.type] then
+            return funcs[class.type]
+        end
+        class = _global_classes[class.btype]
+    end
+    return nil
+end
+
+function get_push_function(t)
+    return _push_functions[t] or search_base(t, _base_push_functions) or "tolua_pushusertype"
+end
+
+function get_to_function(t)
+    return _to_functions[t] or search_base(t, _base_to_functions) or "tolua_tousertype"
+end
+ 
+function get_is_function(t)
+    return _is_functions[t] or search_base(t, _base_is_functions) or "tolua_isusertype"
+end
+
Index: code/branches/pch/src/tolua/lua/class.lua
===================================================================
--- code/branches/pch/src/tolua/lua/class.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/class.lua	(revision 3127)
@@ -64,5 +64,5 @@
 -- return collection requirement
 function classClass:requirecollection (t)
-    if self.flags.protected_destructor then
+    if self.flags.protected_destructor or (not self:check_public_access()) then
         return false
     end
@@ -148,5 +148,5 @@
     -- check for template
     b = string.gsub(b, "^{%s*TEMPLATE_BIND", "{\nTOLUA_TEMPLATE_BIND")
-    local t,_,T,I = string.find(b, "^{%s*TOLUA_TEMPLATE_BIND%s*%(+%s*\"?([^\",]*)\"?%s*,%s*([^%)]*)%s*%)+")
+    local t,_,T,I = string.find(b, '^{%s*TOLUA_TEMPLATE_BIND%s*%(+%s*\"?([^\",]*)\"?%s*,%s*([^%)]*)%s*%)+')
     if t then
 
@@ -159,31 +159,11 @@
         local bs = string.gsub(b, "^{%s*TOLUA_TEMPLATE_BIND[^\n]*\n", "{\n")
 
-        -- replace
-        for i =1 , types.n do
-
-            local Tl = split(T, " ")
-            local Il = split_c_tokens(types[i], " ")
-            local bI = bs
-            local pI = {}
-            for j = 1,Tl.n do
-                Tl[j] = findtype(Tl[j]) or Tl[j]
-                bI = string.gsub(bI, "([^_%w])"..Tl[j].."([^_%w])", "%1"..Il[j].."%2")
-                if p then
-                    for i=1,table.getn(p) do
-                        pI[i] = string.gsub(p[i], "([^_%w]?)"..Tl[j].."([^_%w]?)", "%1"..Il[j].."%2")
-                    end
-                end
-            end
-            --local append = "<"..string.gsub(types[i], "%s+", ",")..">"
-            local append = "<"..concat(Il, 1, table.getn(Il), ",")..">"
-            append = string.gsub(append, "%s*,%s*", ",")
-            append = string.gsub(append, ">>", "> >")
-            for i=1,table.getn(pI) do
-                --pI[i] = string.gsub(pI[i], ">>", "> >")
-                pI[i] = resolve_template_types(pI[i])
-            end
-            bI = string.gsub(bI, ">>", "> >")
-            Class(n..append, pI, bI)
-        end
+        local Tl = split(T, " ")
+        local tc = TemplateClass(n, p, bs, Tl)
+
+        tc:throw(types, true)
+        --for i=1,types.n do
+        --    tc:throw(split_c_tokens(types[i], " "), true)
+        --end
         return
     end
Index: code/branches/pch/src/tolua/lua/code.lua
===================================================================
--- code/branches/pch/src/tolua/lua/code.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/code.lua	(revision 3127)
@@ -47,8 +47,16 @@
     end
 
+    -- pad to 16 bytes
+    local npad = 16 - (#s % 16)
+    local spad = ""
+    for i=1,npad do
+        spad = spad .. "-"
+    end
+    s = s..spad
+
     -- convert to C
     output('\n'..pre..'{ /* begin embedded lua code */\n')
     output(pre..' int top = lua_gettop(tolua_S);')
-    output(pre..' static unsigned char B[] = {\n   ')
+    output(pre..' static const unsigned char B[] = {\n   ')
     local t={n=0}
     local b = gsub(s, '(.)',
Index: code/branches/pch/src/tolua/lua/compat-5.1.lua
===================================================================
--- code/branches/pch/src/tolua/lua/compat-5.1.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/compat-5.1.lua	(revision 3127)
@@ -26,4 +26,7 @@
 
     local f = load(getfile, path)
+    if not f then
+        error("error loading file "..path)
+    end
     return f()
 end
Index: code/branches/pch/src/tolua/lua/container.lua
===================================================================
--- code/branches/pch/src/tolua/lua/container.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/container.lua	(revision 3127)
@@ -615,4 +615,11 @@
             b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
         end
+        if not b then
+            -- try function pointer
+            b,e,decl,arg,const = strfind(s,"^%s*([^%(;\n]+%b())%s*(%b())%s*;%s*")
+            if b then
+                decl = string.gsub(decl, "%(%s*%*([^%)]*)%s*%)", " %1 ")
+            end
+        end
         if b then
             if virt and string.find(virt, "[=0]") then
@@ -647,20 +654,21 @@
         base = '' body = ''
         b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;")  -- dummy class
+        local dummy = false
         if not b then
             b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;")    -- dummy struct
             if not b then
-                b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*([^{]-)%s*(%b{})%s*")
                 if not b then
-                    b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                    b,e,name,base,body = strfind(s,"^%s*struct%s+([_%w][_%w@]*)%s*([^{]-)%s*(%b{})%s*")
                     if not b then
-                        b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                        b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*([^{]-)%s*(%b{})%s*")
                         if not b then
                             base = ''
-                            b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*")
+                            b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;")
                         end
                     end
                 end
-            end
-        end
+            else dummy = 1 end
+        else dummy = 1 end
         if b then
             if base ~= '' then
@@ -675,4 +683,11 @@
             _curr_code = strsub(s,b,e)
             Class(name,base,body)
+            if not dummy then
+                varb,vare,varname = string.find(s, "^%s*([_%w]+)%s*;", e+1)
+                if varb then
+                    Variable(name.." "..varname)
+                    e = vare
+                end
+            end
             return strsub(s,e+1)
         end
@@ -723,5 +738,5 @@
     -- try array
     do
-        local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")
+    local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:<>]*[]_%w%d])%s*;%s*")
         if b then
             _curr_code = strsub(s,b,e)
@@ -743,5 +758,5 @@
 function classContainer:parse (s)
 
-    self.curr_member_access = nil
+    --self.curr_member_access = nil
 
     while s ~= '' do
Index: code/branches/pch/src/tolua/lua/declaration.lua
===================================================================
--- code/branches/pch/src/tolua/lua/declaration.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/declaration.lua	(revision 3127)
@@ -140,11 +140,15 @@
         for i=1, table.getn(m) do
             m[i] = string.gsub(m[i],"%s*([%*&])", "%1")
-            m[i] = findtype(m[i]) or m[i]
-            m[i] = resolve_template_types(m[i])
+            if not isbasic(m[i]) then
+                if not isenum(m[i]) then _, m[i] = applytypedef("", m[i]) end
+                m[i] = findtype(m[i]) or m[i]
+                m[i] = resolve_template_types(m[i])
+            end
         end
 
         local b,i
         type,b,i = break_template(type)
-        local template_part = "<"..string.gsub(concat(m, 1, m.n), " ", ",")..">"
+        --print("concat is ",concat(m, 1, m.n))
+        local template_part = "<"..concat(m, 1, m.n, ",")..">"
         type = rebuild_template(type, b, template_part)
         type = string.gsub(type, ">>", "> >")
@@ -187,8 +191,8 @@
 -- check if array of values are returned to Lua
 function classDeclaration:requirecollection (t)
- if self.mod ~= 'const' and
+    if self.mod ~= 'const' and
         self.dim and self.dim ~= '' and
                  not isbasic(self.type) and
-                 self.ptr == '' then
+                 self.ptr == '' and self:check_public_access() then
         local type = gsub(self.type,"%s*const%s+","")
         t[type] = "tolua_collect_" .. clean_template(type)
@@ -222,11 +226,16 @@
         --    return 'tolua_isstringarray(tolua_S,'..narg..','..def..',&tolua_err)'
         --else
-        return 'tolua_istable(tolua_S,'..narg..',0,&tolua_err)'
+        return '!tolua_istable(tolua_S,'..narg..',0,&tolua_err)'
         --end
     elseif t then
-        return 'tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)'
-    else
-        return 'tolua_isusertype(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err)'
-    end
+        return '!tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)'
+    else
+        local is_func = get_is_function(self.type)
+        if self.ptr == '&' or self.ptr == '' then
+            return '(tolua_isvaluenil(tolua_S,'..narg..',&tolua_err) || !'..is_func..'(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err))'
+        else
+            return '!'..is_func..'(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err)'
+        end
+   end
 end
 
@@ -237,4 +246,5 @@
     local mod
     local type = self.type
+    local nctype = gsub(self.type,'const%s+','')
     if self.dim ~= '' then
         type = gsub(self.type,'const%s+','')  -- eliminates const modifier for arrays
@@ -251,5 +261,5 @@
         else
             if cplusplus then
-                line = concatparam(line,' = new',type,ptr,'['..self.dim..'];')
+                line = concatparam(line,' = Mtolua_new_dim(',type,ptr,', '..self.dim..');')
             else
                 line = concatparam(line,' = (',type,ptr,'*)',
@@ -273,5 +283,5 @@
             end
             line = concatparam(line,') ')
-            if isenum(type) then
+            if isenum(nctype) then
                 line = concatparam(line,'(int) ')
             end
@@ -286,5 +296,6 @@
                 line = concatparam(line,'tolua_to'..t,'(tolua_S,',narg,',',def,'));')
             else
-                line = concatparam(line,'tolua_tousertype(tolua_S,',narg,',',def,'));')
+                local to_func = get_to_function(type)
+                line = concatparam(line,to_func..'(tolua_S,',narg,',',def,'));')
             end
         end
@@ -361,5 +372,5 @@
                 output('   {')
                 output('#ifdef __cplusplus\n')
-                output('    void* tolua_obj = new',type,'(',self.name,'[i]);')
+                output('    void* tolua_obj = Mtolua_new((',type,')(',self.name,'[i]));')
                 output('    tolua_pushfieldusertype_and_takeownership(tolua_S,',narg,',i+1,tolua_obj,"',type,'");')
                 output('#else\n')
@@ -380,5 +391,5 @@
     if self.dim ~= '' and tonumber(self.dim)==nil then
         output('#ifdef __cplusplus\n')
-        output('  delete []',self.name,';')
+        output('  Mtolua_delete_dim(',self.name,');')
         output('#else\n')
         output('  free(',self.name,');')
@@ -405,5 +416,6 @@
             output('   tolua_push'..t..'(tolua_S,(',ct,')'..self.name..');')
         else
-            output('   tolua_pushusertype(tolua_S,(void*)'..self.name..',"',self.type,'");')
+            local push_func = get_push_function(self.type)
+            output('   ',push_func,'(tolua_S,(void*)'..self.name..',"',self.type,'");')
         end
         return 1
Index: code/branches/pch/src/tolua/lua/doit.lua
===================================================================
--- code/branches/pch/src/tolua/lua/doit.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/doit.lua	(revision 3127)
@@ -16,5 +16,5 @@
     for k,v in ipairs(_extra_parameters or {}) do
         
-        local b,e,name,value = string.find(v, "^([^=])=(.*)$")
+        local b,e,name,value = string.find(v, "^([^=]*)=(.*)$")
         if b then
             _extra_parameters[name] = value
@@ -94,6 +94,12 @@
         p:print()
     else
+        push(p)
+        pre_output_hook(p)
+        pop()
         p:preamble()
         p:supcode()
+        push(p)
+        pre_register_hook(p)
+        pop()
         p:register()
         push(p)
Index: code/branches/pch/src/tolua/lua/enumerate.lua
===================================================================
--- code/branches/pch/src/tolua/lua/enumerate.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/enumerate.lua	(revision 3127)
@@ -22,9 +22,14 @@
 -- register enumeration
 function classEnumerate:register (pre)
+    if not self:check_public_access() then
+        return
+    end
     pre = pre or ''
     local nspace = getnamespace(classContainer.curr)
     local i=1
     while self[i] do
-        output(pre..'tolua_constant(tolua_S,"'..self.lnames[i]..'",'..nspace..self[i]..');')
+        if self.lnames[i] and self.lnames[i] ~= "" then
+            output(pre..'tolua_constant(tolua_S,"'..self.lnames[i]..'",'..nspace..self[i]..');')
+        end
         i = i+1
     end
@@ -56,4 +61,9 @@
             Variable("tolua_readonly int "..varname)
         end
+    end
+    local parent = classContainer.curr
+    if parent then
+        t.access = parent.curr_member_access
+        t.global_access = t:check_public_access()
     end
     return t
Index: code/branches/pch/src/tolua/lua/feature.lua
===================================================================
--- code/branches/pch/src/tolua/lua/feature.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/feature.lua	(revision 3127)
@@ -48,8 +48,10 @@
         local n = split(self.name,'@')
         self.name = n[1]
+        self.name = string.gsub(self.name, ":%d*$", "")
         if not n[2] then
             n[2] = applyrenaming(n[1])
         end
         self.lname = n[2] or gsub(n[1],"%[.-%]","")
+        self.lname = string.gsub(self.lname, ":%d*$", "")
         self.original_name = self.name
         self.lname = clean_template(self.lname)
@@ -62,4 +64,5 @@
     if parent then
         self.access = parent.curr_member_access
+        self.global_access = self:check_public_access()
     else
     end
@@ -67,4 +70,8 @@
 
 function classFeature:check_public_access()
+
+    if type(self.global_access) == "boolean" then
+        return self.global_access
+    end
 
     if self.access and self.access ~= 0 then
@@ -122,5 +129,9 @@
     end
 
-    n = string.gsub(n..'_'.. (self.lname or self.name), "[<>:, \.%*&]", "_")
+    local fname = self.lname
+    if not fname or fname == '' then
+        fname = self.name
+    end
+    n = string.gsub(n..'_'.. (fname), "[<>:, \.%*&]", "_")
 
     return n
Index: code/branches/pch/src/tolua/lua/function.lua
===================================================================
--- code/branches/pch/src/tolua/lua/function.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/function.lua	(revision 3127)
@@ -209,5 +209,5 @@
     if class then narg=2 else narg=1 end
     if class then
-        local func = 'tolua_isusertype'
+        local func = get_is_function(self.parent.type)
         local type = self.parent.type
         if self.name=='new' or static~=nil then
@@ -226,5 +226,5 @@
             local btype = isbasic(self.args[i].type)
             if btype ~= 'value' and btype ~= 'state' then
-                output('     !'..self.args[i]:outchecktype(narg)..' ||\n')
+                output('     '..self.args[i]:outchecktype(narg)..' ||\n')
             end
             if btype ~= 'state' then
@@ -250,5 +250,6 @@
         output(' ',self.const,self.parent.type,'*','self = ')
         output('(',self.const,self.parent.type,'*) ')
-        output('tolua_tousertype(tolua_S,1,0);')
+        local to_func = get_to_function(self.parent.type)
+        output(to_func,'(tolua_S,1,0);')
     elseif static then
         _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
@@ -269,5 +270,5 @@
     if class and self.name~='new' and static==nil then
         output('#ifndef TOLUA_RELEASE\n')
-        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
+        output('  if (!self) tolua_error(tolua_S,"'..output_error_hook("invalid \'self\' in function \'%s\'", self.name)..'", NULL);');
         output('#endif\n')
     end
@@ -312,4 +313,6 @@
     --------------------------------------------------
 
+    pre_call_hook(self)
+
     local out = string.find(self.mod, "tolua_outside")
 
@@ -323,5 +326,5 @@
     -- call function
     if class and self.name=='delete' then
-        output('  delete self;')
+        output('  Mtolua_delete(self);')
     elseif class and self.name == 'operator&[]' then
         if flags['1'] then -- for compatibility with tolua5 ?
@@ -352,5 +355,5 @@
     end
     if class and self.name=='new' then
-        output('new',self.type,'(')
+        output('Mtolua_new((',self.type,')(')
     elseif class and static then
         if out then
@@ -364,5 +367,6 @@
         else
             if self.cast_operator then
-                output('static_cast<',self.mod,self.type,self.ptr,'>(*self')
+                --output('static_cast<',self.mod,self.type,self.ptr,' >(*self')
+                output('self->operator ',self.mod,self.type,'(')
             else
                 output('self->'..self.name,'(')
@@ -392,5 +396,9 @@
         output('-1);')
     else
-        output(');')
+        if class and self.name=='new' then
+            output('));') -- close Mtolua_new(
+        else
+            output(');')
+        end
     end
 
@@ -399,5 +407,5 @@
         nret = nret + 1
         local t,ct = isbasic(self.type)
-        if t then
+        if t and self.name ~= "new" then
             if self.cast_operator and _basic_raw_push[t] then
                 output('   ',_basic_raw_push[t],'(tolua_S,(',ct,')tolua_ret);')
@@ -408,21 +416,27 @@
                 t = self.type
                 new_t = string.gsub(t, "const%s+", "")
+                local owned = false
+                if string.find(self.mod, "tolua_owned") then
+                    owned = true
+                end
+                local push_func = get_push_function(t)
                 if self.ptr == '' then
                     output('   {')
                     output('#ifdef __cplusplus\n')
-                    output('    void* tolua_obj = new',new_t,'(tolua_ret);')
-                    output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+                    output('    void* tolua_obj = Mtolua_new((',new_t,')(tolua_ret));')
+                    output('    ',push_func,'(tolua_S,tolua_obj,"',t,'");')
+                    output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
                     output('#else\n')
                     output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
-                    output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+                    output('    ',push_func,'(tolua_S,tolua_obj,"',t,'");')
+                    output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
                     output('#endif\n')
                     output('   }')
                 elseif self.ptr == '&' then
-                    output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
+                    output('   ',push_func,'(tolua_S,(void*)&tolua_ret,"',t,'");')
                 else
-                    if local_constructor then
-                        output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
-                    else
-                        output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
+                    output('   ',push_func,'(tolua_S,(void*)tolua_ret,"',t,'");')
+                    if owned or local_constructor then
+                        output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
                     end
                 end
@@ -466,4 +480,6 @@
     end
 
+    post_call_hook(self)
+
     output(' }')
     output(' return '..nret..';')
@@ -474,5 +490,5 @@
         output('#ifndef TOLUA_RELEASE\n')
         output('tolua_lerror:\n')
-        output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
+        output(' tolua_error(tolua_S,"'..output_error_hook("#ferror in function \'%s\'.", self.lname)..'",&tolua_err);')
         output(' return 0;')
         output('#endif\n')
@@ -574,5 +590,5 @@
     if string.find(par, "%*") then -- it's a pointer with a default value
 
-        if string.find(par, '=%s*new') then -- it's a pointer with an instance as default parameter.. is that valid?
+        if string.find(par, '=%s*new') or string.find(par, "%(") then -- it's a pointer with an instance as default parameter.. is that valid?
             return true
         end
@@ -661,5 +677,5 @@
         --ns = strip_defaults(ns)
 
-        Function(d, ns, c)
+        local f = Function(d, ns, c)
         for i=1,last do
             t[i] = string.gsub(t[i], "=.*$", "")
Index: code/branches/pch/src/tolua/lua/operator.lua
===================================================================
--- code/branches/pch/src/tolua/lua/operator.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/operator.lua	(revision 3127)
@@ -75,5 +75,6 @@
     output(' if (\n')
     -- check self
-    output('     !'..'tolua_isusertype(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n')
+    local is_func = get_is_function(self.parent.type)
+    output('     !'..is_func..'(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n')
     output('     !tolua_isnoobj(tolua_S,2,&tolua_err)\n )')
     output('  goto tolua_lerror;')
@@ -86,9 +87,10 @@
     output(' ',self.const,self.parent.type,'*','self = ')
     output('(',self.const,self.parent.type,'*) ')
-    output('tolua_tousertype(tolua_S,1,0);')
+    local to_func = get_to_func(self.parent.type)
+    output(to_func,'(tolua_S,1,0);')
 
     -- check self
     output('#ifndef TOLUA_RELEASE\n')
-    output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
+    output('  if (!self) tolua_error(tolua_S,"'..output_error_hook("invalid \'self\' in function \'%s\'", self.name)..'",NULL);');
     output('#endif\n')
 
@@ -103,22 +105,26 @@
     else
         t = self.type
+        local push_func = get_push_function(t)
         new_t = string.gsub(t, "const%s+", "")
         if self.ptr == '' then
             output('   {')
             output('#ifdef __cplusplus\n')
-            output('    void* tolua_obj = new',new_t,'(tolua_ret);')
-            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+            output('    void* tolua_obj = Mtolua_new((',new_t,')(tolua_ret));')
+            output('    ',push_func,'(tolua_S,tolua_obj,"',t,'");')
+            output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
             output('#else\n')
             output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
-            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+            output('    ',push_func,'(tolua_S,tolua_obj,"',t,'");')
+            output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
             output('#endif\n')
             output('   }')
         elseif self.ptr == '&' then
-            output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
+            output('   ',push_func,'(tolua_S,(void*)&tolua_ret,"',t,'");')
         else
             if local_constructor then
-                output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
+                output('   ',push_func,'(tolua_S,(void *)tolua_ret,"',t,'");')
+                output('    tolua_register_gc(tolua_S,lua_gettop(tolua_S));')
             else
-                output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
+                output('   ',push_func,'(tolua_S,(void*)tolua_ret,"',t,'");')
             end
         end
@@ -130,5 +136,5 @@
     output('#ifndef TOLUA_RELEASE\n')
     output('tolua_lerror:\n')
-    output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
+    output(' tolua_error(tolua_S,"'..output_error_hook("#ferror in function \'%s\'.", self.lname)..'",&tolua_err);')
     output(' return 0;')
     output('#endif\n')
Index: code/branches/pch/src/tolua/lua/package.lua
===================================================================
--- code/branches/pch/src/tolua/lua/package.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/package.lua	(revision 3127)
@@ -42,6 +42,5 @@
                                                return "\n#["..getn(L).."]#"
                                            end
-    )
-    -- avoid preprocessing embedded C code
+    )    -- avoid preprocessing embedded C code
     local C = {}
     self.code = gsub(self.code,"\n%s*%$%<","\3") -- deal with embedded C code
@@ -51,6 +50,5 @@
                                                return "\n#<"..getn(C)..">#"
                                            end
-    )
-    -- avoid preprocessing embedded C code
+    )    -- avoid preprocessing embedded C code
     self.code = gsub(self.code,"\n%s*%$%{","\5") -- deal with embedded C code
     self.code = gsub(self.code,"\n%s*%$%}","\6")
@@ -60,5 +58,4 @@
                                            end
     )
-
     --self.code = gsub(self.code,"\n%s*#[^d][^\n]*\n", "\n\n") -- eliminate preprocessor directives that don't start with 'd'
     self.code = gsub(self.code,"\n[ \t]*#[ \t]*[^d%<%[]", "\n//") -- eliminate preprocessor directives that don't start with 'd'
@@ -71,5 +68,4 @@
                                                          end
     )
-
     -- perform global substitution
 
@@ -94,23 +90,18 @@
                                                     return L[tonumber(n)]
                                                 end
-    )
-    -- restore embedded C code
+    )    -- restore embedded C code
     self.code = gsub(self.code,"%#%<(%d+)%>%#", function (n)
                                                     return C[tonumber(n)]
                                                 end
-    )
-    -- restore verbatim lines
+    )    -- restore verbatim lines
     self.code = gsub(self.code,"%#(%d+)%#", function (n)
                                                 return V[tonumber(n)]
                                             end
     )
-
     self.code = string.gsub(self.code, "\n%s*%$([^\n]+)", function (l)
                                                               Verbatim(l.."\n")
                                                               return "\n"
                                                           end
-    )
-end
-
+    )end
 -- translate verbatim
 function classPackage:preamble ()
@@ -146,5 +137,5 @@
             output('{')
             output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
-            output('    delete self;')
+            output('    Mtolua_delete(self);')
             output('    return 0;')
             output('}')
@@ -157,9 +148,16 @@
     output('static void tolua_reg_types (lua_State* tolua_S)')
     output('{')
-    foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end)
+
     if flags.t then
         output("#ifndef Mtolua_typeid\n#define Mtolua_typeid(L,TI,T)\n#endif\n")
-        foreach(_usertype,function(n,v) output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");') end)
-    end
+    end
+    foreach(_usertype,function(n,v)
+        if (not _global_classes[v]) or _global_classes[v]:check_public_access() then
+            output(' tolua_usertype(tolua_S,"',v,'");')
+            if flags.t then
+                output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");')
+            end
+        end
+    end)
     output('}')
     output('\n')
@@ -191,5 +189,5 @@
     output(pre.."int luaopen_"..self.name.." (lua_State* tolua_S) {")
     output(pre.." return tolua_"..self.name.."_open(tolua_S);")
-    output(pre.."};")
+    output(pre.."}")
     output("#endif\n\n")
 
@@ -204,10 +202,7 @@
 
     if flags.H then
-        local package_lower = string.lower(self.name)
-        output('#include "'..package_lower..'/'..self.name..'Prereqs.h"\n')
-        output('/* Exported function */')
+        local package_lower = string.lower(self.name)        output('#include "'..package_lower..'/'..self.name..'Prereqs.h"\n')        output('/* Exported function */')
         output('_'..self.name..'Export')
-        output('int  tolua_'..self.name..'_open (lua_State* tolua_S);')
-        output('\n')
+        output('int  tolua_'..self.name..'_open (lua_State* tolua_S);')        output('\n')
     end
 end
@@ -224,9 +219,5 @@
     local code = '\n$#include "'..string.lower(flags.n)..'/'..fn..'"\n'
     s= "\n" .. s .. "\n" -- add blank lines as sentinels
-
-    -- eliminate export macro problems in class declarations
-    s = gsub(s, ' _%w*Export ', ' ')
-
-    local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
+    -- eliminate export macro problems in class declarations    s = gsub(s, ' _%w*Export ', ' ')    local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
     while e do
         t = strlower(t)
@@ -249,24 +240,20 @@
 
     -- open input file, if any
+    local st,msg
     if fn then
         local file
-        if flags.f then
-            if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then
-                file = flags.f
-            else
-                file = flags.w..'/'..flags.f
-            end
-        else
-            file = flags.f
-        end
-        local st, msg = readfrom(file)
-        if not st then
+        if flags.f then            if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then                file = flags.f            else                file = flags.w..'/'..flags.f            end        else            file = flags.f        end        st, msg = readfrom(flags.f)        if not st then
             error('#'..msg..' path: '..flags.f)
         end
         local _; _, _, ext = strfind(fn,".*%.(.*)$")
     end
-    local code = "\n" .. read('*a')
-    if ext == 'h' or ext == 'hpp' then
-        code = extract_code(fn,code)
+    local code
+    if ext == 'pkg' then
+        code = prep(st)
+    else
+        code = "\n" .. read('*a')
+        if ext == 'h' or ext == 'hpp' then
+            code = extract_code(fn,code)
+        end
     end
 
@@ -276,19 +263,5 @@
     end
 
-    -- prepare working directory
-    local current_path
-    if not flags.w and flags.f then
-        current_path = gsub(flags.f, '(/)[^/]*%.?[^/]*$', '%1')
-    elseif flags.w then
-        if not (string.sub(flags.w, string.len(flags.w)) == '/') then
-            current_path = flags.w..'/'
-        else
-            current_path = flags.w
-        end
-    else
-        current_path = ''
-    end
-
-    -- deal with include directive
+    -- prepare working directory    local current_path    if not flags.w and flags.f then        current_path = gsub(flags.f, '(/)[^/]*%.?[^/]*$', '%1')    elseif flags.w then        if not (string.sub(flags.w, string.len(flags.w)) == '/') then            current_path = flags.w..'/'        else            current_path = flags.w        end    else        current_path = ''    end    -- deal with include directive
     local nsubst
     repeat
@@ -300,10 +273,13 @@
                     error('#'..msg..': '..fn)
                 end
+                if kind == 'p' then
+                    local s = prep(fp)
+                    closefile(fp)
+                    return s
+                end
                 local s = read(fp,'*a')
                 closefile(fp)
                 if kind == 'c' or kind == 'h' then
                     return extract_code(fn,s)
-                elseif kind == 'p' then
-                    return "\n\n" .. s
                 elseif kind == 'l' then
                     return "\n$[--##"..fn.."\n" .. s .. "\n$]\n"
@@ -318,6 +294,5 @@
                 end
             end
-        )
-    until nsubst==0
+        )    until nsubst==0
 
     -- deal with renaming directive
@@ -337,2 +312,31 @@
 
 
+setmetatable(_extra_parameters, { __index = _G })
+
+function prep(file)
+
+    local chunk = {'local __ret = {"\\n"}\n'}
+    for line in file:lines() do
+       if string.find(line, "^##") then
+           table.insert(chunk, string.sub(line, 3) .. "\n")
+       else
+           local last = 1
+           for text, expr, index in string.gfind(line, "(.-)$(%b())()") do 
+               last = index
+               if text ~= "" then
+                   table.insert(chunk, string.format('table.insert(__ret, %q )', text))
+               end
+               table.insert(chunk, string.format('table.insert(__ret, %s )', expr))
+           end
+           table.insert(chunk, string.format('table.insert(__ret, %q)\n',
+                               string.sub(line, last).."\n"))
+       end
+    end
+    table.insert(chunk, '\nreturn table.concat(__ret)\n')
+    local f,e = loadstring(table.concat(chunk))
+    if e then
+        error("#"..e)
+    end
+    setfenv(f, _extra_parameters)
+    return f()
+end
Index: code/branches/pch/src/tolua/lua/template_class.lua
===================================================================
--- code/branches/pch/src/tolua/lua/template_class.lua	(revision 3127)
+++ code/branches/pch/src/tolua/lua/template_class.lua	(revision 3127)
@@ -0,0 +1,82 @@
+
+_global_templates = {}
+
+classTemplateClass = {
+
+    name = '',
+    body = '',
+    parents = {},
+    args = {}, -- the template arguments
+}
+
+classTemplateClass.__index = classTemplateClass
+
+
+function classTemplateClass:throw(types, local_scope)
+
+    --if table.getn(types) ~= table.getn(self.args) then
+    --    error("#invalid parameter count")
+    --end
+
+    -- replace
+    for i =1 , types.n do
+
+        local Il = split_c_tokens(types[i], " ")
+        if table.getn(Il) ~= table.getn(self.args) then
+            error("#invalid parameter count for "..types[i])
+        end
+        local bI = self.body
+        local pI = {}
+        for j = 1,self.args.n do
+            --Tl[j] = findtype(Tl[j]) or Tl[j]
+            bI = string.gsub(bI, "([^_%w])"..self.args[j].."([^_%w])", "%1"..Il[j].."%2")
+            if self.parents then
+                for i=1,table.getn(self.parents) do
+                    pI[i] = string.gsub(self.parents[i], "([^_%w]?)"..self.args[j].."([^_%w]?)", "%1"..Il[j].."%2")
+                end
+            end
+        end
+        --local append = "<"..string.gsub(types[i], "%s+", ",")..">"
+        local append = "<"..concat(Il, 1, table.getn(Il), ",")..">"
+        append = string.gsub(append, "%s*,%s*", ",")
+        append = string.gsub(append, ">>", "> >")
+        for i=1,table.getn(pI) do
+            --pI[i] = string.gsub(pI[i], ">>", "> >")
+            pI[i] = resolve_template_types(pI[i])
+        end
+        bI = string.gsub(bI, ">>", "> >")
+        local n = self.name
+        if local_scope then
+            n = self.local_name
+        end
+
+        Class(n..append, pI, bI)
+    end
+end
+
+
+function TemplateClass(name, parents, body, parameters)
+
+    local o = {
+    
+        parents = parents,
+        body = body,
+        args = parameters,
+    }
+    
+    local oname = string.gsub(name, "@.*$", "")
+    oname = getnamespace(classContainer.curr)..oname
+    o.name = oname
+
+    o.local_name = name
+    
+    setmetatable(o, classTemplateClass)
+
+    if _global_templates[oname] then
+        warning("Duplicate declaration of template "..oname)
+    else
+        _global_templates[oname] = o
+    end
+
+    return o
+end
Index: code/branches/pch/src/tolua/lua/variable.lua
===================================================================
--- code/branches/pch/src/tolua/lua/variable.lua	(revision 3126)
+++ code/branches/pch/src/tolua/lua/variable.lua	(revision 3127)
@@ -109,5 +109,5 @@
     if string.find(self.mod, 'tolua_property') then
 
-        _,_,type = string.find(self.mod, "tolua_property__([^%s]*)")
+        local _,_,type = string.find(self.mod, "tolua_property__([^%s]*)")
         type = type or "default"
         prop_get,prop_set = get_property_methods(type, self.name)
@@ -131,5 +131,6 @@
         output(' ',self.parent.type,'*','self = ')
         output('(',self.parent.type,'*) ')
-        output('tolua_tousertype(tolua_S,1,0);')
+        local to_func = get_to_function(self.parent.type)
+        output(to_func,'(tolua_S,1,0);')
     elseif static then
         _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
@@ -140,5 +141,5 @@
     if class and static==nil then
         output('#ifndef TOLUA_RELEASE\n')
-        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
+        output('  if (!self) tolua_error(tolua_S,"'..output_error_hook("invalid \'self\' in accessing variable \'%s\'", self.name)..'",NULL);');
         output('#endif\n')
     end
@@ -146,8 +147,9 @@
     -- return value
     if string.find(self.mod, 'tolua_inherits') then
+    local push_func = get_push_function(self.type)
         output('#ifdef __cplusplus\n')
-        output('  tolua_pushusertype(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");')
+        output('  ',push_func,'(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");')
         output('#else\n')
-        output('  tolua_pushusertype(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");')
+        output('  ',push_func,'(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");')
         output('#endif\n')
     else
@@ -156,9 +158,10 @@
             output('  tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static,prop_get)..');')
         else
+            local push_func = get_push_function(self.type)
             t = self.type
             if self.ptr == '&' or self.ptr == '' then
-                output('  tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static,prop_get)..',"',t,'");')
-            else
-                output('  tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static,prop_get)..',"',t,'");')
+                output('  ',push_func,'(tolua_S,(void*)&'..self:getvalue(class,static,prop_get)..',"',t,'");')
+            else
+                output('  ',push_func,'(tolua_S,(void*)'..self:getvalue(class,static,prop_get)..',"',t,'");')
             end
         end
@@ -185,5 +188,6 @@
         output(' ',self.parent.type,'*','self = ')
         output('(',self.parent.type,'*) ')
-        output('tolua_tousertype(tolua_S,1,0);')
+        local to_func = get_to_function(self.parent.type)
+        output(to_func,'(tolua_S,1,0);')
         -- check self value
     end
@@ -192,5 +196,5 @@
     output('  tolua_Error tolua_err;')
     if class and static==nil then
-        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
+        output('  if (!self) tolua_error(tolua_S,"'..output_error_hook("invalid \'self\' in accessing variable \'%s\'", self.name)..'",NULL);');
     elseif static then
         _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
@@ -198,5 +202,5 @@
 
     -- check variable type
-    output('  if (!'..self:outchecktype(2)..')')
+    output('  if ('..self:outchecktype(2)..')')
     output('   tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);')
     output('#endif\n')
@@ -206,5 +210,5 @@
     if self.def ~= '' then def = self.def end
     if self.type == 'char*' and self.dim ~= '' then -- is string
-        output(' strncpy(')
+        output(' strncpy((char*)')
         if class and static then
             output(self.parent.type..'::'..self.name)
@@ -214,5 +218,5 @@
                 output(self.name)
             end
-            output(',tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);')
+            output(',(const char*)tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);')
         else
             local ptr = ''
@@ -245,5 +249,6 @@
                 output('tolua_to'..t,'(tolua_S,2,',def,'))')
             else
-                output('tolua_tousertype(tolua_S,2,',def,'))')
+                local to_func = get_to_function(self.type)
+                output(to_func,'(tolua_S,2,',def,'))')
             end
             if prop_set then
Index: code/branches/pch/src/tolua/tolua++.h
===================================================================
--- code/branches/pch/src/tolua/tolua++.h	(revision 3126)
+++ code/branches/pch/src/tolua/tolua++.h	(revision 3127)
@@ -58,6 +58,10 @@
 #define tolua_pushfieldcppstring(L,lo,idx,s) tolua_pushfieldstring(L, lo, idx, s.c_str())
 
-#define TEMPLATE_BIND(p)
+#ifndef TEMPLATE_BIND
+ #define TEMPLATE_BIND(p)
+#endif
+
 #define TOLUA_TEMPLATE_BIND(p)
+
 #define TOLUA_PROTECTED_DESTRUCTOR
 #define TOLUA_PROPERTY_TYPE(p)
@@ -79,7 +83,8 @@
 
 TOLUA_API const char* tolua_typename (lua_State* L, int lo);
-TOLUA_API void tolua_error (lua_State* L, char* msg, tolua_Error* err);
+TOLUA_API void tolua_error (lua_State* L, const char* msg, tolua_Error* err);
 TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err);
 TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err);
+TOLUA_API int tolua_isvaluenil (lua_State* L, int lo, tolua_Error* err);
 TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err);
 TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err);
@@ -110,14 +115,14 @@
 TOLUA_API int tolua_default_collect (lua_State* tolua_S);
 
-TOLUA_API void tolua_usertype (lua_State* L, char* type);
-TOLUA_API void tolua_beginmodule (lua_State* L, char* name);
+TOLUA_API void tolua_usertype (lua_State* L, const char* type);
+TOLUA_API void tolua_beginmodule (lua_State* L, const char* name);
 TOLUA_API void tolua_endmodule (lua_State* L);
-TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar);
-TOLUA_API void tolua_class (lua_State* L, char* name, char* base);
-TOLUA_API void tolua_cclass (lua_State* L, char* lname, char* name, char* base, lua_CFunction col);
-TOLUA_API void tolua_function (lua_State* L, char* name, lua_CFunction func);
-TOLUA_API void tolua_constant (lua_State* L, char* name, double value);
-TOLUA_API void tolua_variable (lua_State* L, char* name, lua_CFunction get, lua_CFunction set);
-TOLUA_API void tolua_array (lua_State* L,char* name, lua_CFunction get, lua_CFunction set);
+TOLUA_API void tolua_module (lua_State* L, const char* name, int hasvar);
+TOLUA_API void tolua_class (lua_State* L, const char* name, const char* base);
+TOLUA_API void tolua_cclass (lua_State* L, const char* lname, const char* name, const char* base, lua_CFunction col);
+TOLUA_API void tolua_function (lua_State* L, const char* name, lua_CFunction func);
+TOLUA_API void tolua_constant (lua_State* L, const char* name, lua_Number value);
+TOLUA_API void tolua_variable (lua_State* L, const char* name, lua_CFunction get, lua_CFunction set);
+TOLUA_API void tolua_array (lua_State* L,const char* name, lua_CFunction get, lua_CFunction set);
 
 /* TOLUA_API void tolua_set_call_event(lua_State* L, lua_CFunction func, char* type); */
@@ -126,5 +131,5 @@
 TOLUA_API void tolua_pushvalue (lua_State* L, int lo);
 TOLUA_API void tolua_pushboolean (lua_State* L, int value);
-TOLUA_API void tolua_pushnumber (lua_State* L, double value);
+TOLUA_API void tolua_pushnumber (lua_State* L, lua_Number value);
 TOLUA_API void tolua_pushstring (lua_State* L, const char* value);
 TOLUA_API void tolua_pushuserdata (lua_State* L, void* value);
@@ -133,5 +138,5 @@
 TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v);
 TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v);
-TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, double v);
+TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, lua_Number v);
 TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v);
 TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v);
@@ -139,5 +144,5 @@
 TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type);
 
-TOLUA_API double tolua_tonumber (lua_State* L, int narg, double def);
+TOLUA_API lua_Number tolua_tonumber (lua_State* L, int narg, lua_Number def);
 TOLUA_API const char* tolua_tostring (lua_State* L, int narg, const char* def);
 TOLUA_API void* tolua_touserdata (lua_State* L, int narg, void* def);
@@ -145,5 +150,5 @@
 TOLUA_API int tolua_tovalue (lua_State* L, int narg, int def);
 TOLUA_API int tolua_toboolean (lua_State* L, int narg, int def);
-TOLUA_API double tolua_tofieldnumber (lua_State* L, int lo, int index, double def);
+TOLUA_API lua_Number tolua_tofieldnumber (lua_State* L, int lo, int index, lua_Number def);
 TOLUA_API const char* tolua_tofieldstring (lua_State* L, int lo, int index, const char* def);
 TOLUA_API void* tolua_tofielduserdata (lua_State* L, int lo, int index, void* def);
@@ -176,4 +181,28 @@
 TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index);
 
+#ifndef Mtolua_new
+#define Mtolua_new(EXP) new EXP
+#endif
+
+#ifndef Mtolua_delete
+#define Mtolua_delete(EXP) delete EXP
+#endif
+
+#ifndef Mtolua_new_dim
+#define Mtolua_new_dim(EXP, len) new EXP[len]
+#endif
+
+#ifndef Mtolua_delete_dim
+#define Mtolua_delete_dim(EXP) delete [] EXP
+#endif
+
+#ifndef tolua_outside
+#define tolua_outside
+#endif
+
+#ifndef tolua_owned
+#define tolua_owned
+#endif
+
 #ifdef __cplusplus
 }
Index: code/branches/pch/src/tolua/tolua.c
===================================================================
--- code/branches/pch/src/tolua/tolua.c	(revision 3126)
+++ code/branches/pch/src/tolua/tolua.c	(revision 3127)
@@ -50,4 +50,5 @@
          "  -E  value[=value] : add extra values to the luastate\n"
          "  -t       : export a list of types asociates with the C++ typeid name\n"
+         "  -q       : don't print warnings to the console\n"
          "  -h       : print this message.\n"
          "Should the input file be omitted, stdin is assumed;\n"
@@ -149,4 +150,5 @@
      case 'E': add_extra(L,argv[++i]); break;
      case 't': setfield(L,t,"t",""); break;
+     case 'q': setfield(L,t,"q",""); break;
      default: error(argv[i]); break;
     }
Index: code/branches/pch/src/tolua/tolua_event.c
===================================================================
--- code/branches/pch/src/tolua/tolua_event.c	(revision 3126)
+++ code/branches/pch/src/tolua/tolua_event.c	(revision 3127)
@@ -372,5 +372,28 @@
 static int class_eq_event (lua_State* L)
 {
-	return do_operator(L,".eq");
+	/* copying code from do_operator here to return false when no operator is found */
+	if (lua_isuserdata(L,1))
+	{
+		/* Try metatables */
+		lua_pushvalue(L,1);                     /* stack: op1 op2 */
+		while (lua_getmetatable(L,-1))
+		{                                       /* stack: op1 op2 op1 mt */
+			lua_remove(L,-2);                      /* stack: op1 op2 mt */
+			lua_pushstring(L,".eq");                  /* stack: op1 op2 mt key */
+			lua_rawget(L,-2);                      /* stack: obj key mt func */
+			if (lua_isfunction(L,-1))
+			{
+				lua_pushvalue(L,1);
+				lua_pushvalue(L,2);
+				lua_call(L,2,1);
+				return 1;
+			}
+			lua_settop(L,3);
+		}
+	}
+
+	lua_settop(L, 3);
+	lua_pushboolean(L, 0);
+	return 1;
 }
 
Index: code/branches/pch/src/tolua/tolua_is.c
===================================================================
--- code/branches/pch/src/tolua/tolua_is.c	(revision 3126)
+++ code/branches/pch/src/tolua/tolua_is.c	(revision 3127)
@@ -86,5 +86,5 @@
 }
 
-TOLUA_API void tolua_error (lua_State* L, char* msg, tolua_Error* err)
+TOLUA_API void tolua_error (lua_State* L, const char* msg, tolua_Error* err)
 {
 	if (msg[0] == '#')
@@ -117,5 +117,5 @@
 
 /* the equivalent of lua_is* for usertable */
-static  int lua_isusertable (lua_State* L, int lo, const char* type)
+static  int lua_isusertable (lua_State* L, int lo, const const char* type)
 {
 	int r = 0;
@@ -213,4 +213,91 @@
  return 0;
 }
+
+TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isnil(L,lo) || lua_isboolean(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "boolean";
+	return 0;
+}
+
+TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isnumber(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "number";
+	return 0;
+}
+
+TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+ if (lua_isnil(L,lo) || lua_isstring(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "string";
+	return 0;
+}
+
+TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_istable(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "table";
+	return 0;
+}
+
+TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isusertable(L,lo,type))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = type;
+	return 0;
+}
+
+
+TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isnil(L,lo) || lua_isuserdata(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "userdata";
+	return 0;
+}
+
+TOLUA_API int tolua_isvaluenil (lua_State* L, int lo, tolua_Error* err) {
+
+	if (lua_gettop(L)<abs(lo))
+		return 0; /* somebody else should chack this */
+	if (!lua_isnil(L, lo))
+		return 0;
+	
+	err->index = lo;
+	err->array = 0;
+	err->type = "value";
+	return 1;
+};
+
 TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err)
 {
@@ -220,77 +307,4 @@
 	err->array = 0;
 	err->type = "value";
-	return 0;
-}
-
-TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err)
-{
-	if (def && lua_gettop(L)<abs(lo))
-		return 1;
-	if (lua_isnil(L,lo) || lua_isboolean(L,lo))
-		return 1;
-	err->index = lo;
-	err->array = 0;
-	err->type = "boolean";
-	return 0;
-}
-
-TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err)
-{
-	if (def && lua_gettop(L)<abs(lo))
-		return 1;
-	if (lua_isnumber(L,lo))
-		return 1;
-	err->index = lo;
-	err->array = 0;
-	err->type = "number";
-	return 0;
-}
-
-TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err)
-{
-	if (def && lua_gettop(L)<abs(lo))
-		return 1;
- if (lua_isnil(L,lo) || lua_isstring(L,lo))
-		return 1;
-	err->index = lo;
-	err->array = 0;
-	err->type = "string";
-	return 0;
-}
-
-TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err)
-{
-	if (def && lua_gettop(L)<abs(lo))
-		return 1;
-	if (lua_istable(L,lo))
-		return 1;
-	err->index = lo;
-	err->array = 0;
-	err->type = "table";
-	return 0;
-}
-
-TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
-{
-	if (def && lua_gettop(L)<abs(lo))
-		return 1;
-	if (lua_isusertable(L,lo,type))
-		return 1;
-	err->index = lo;
-	err->array = 0;
-	err->type = type;
-	return 0;
-}
-
-
-TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err)
-{
-	if (def && lua_gettop(L)<abs(lo))
-		return 1;
-	if (lua_isnil(L,lo) || lua_isuserdata(L,lo))
-		return 1;
-	err->index = lo;
-	err->array = 0;
-	err->type = "userdata";
 	return 0;
 }
Index: code/branches/pch/src/tolua/tolua_map.c
===================================================================
--- code/branches/pch/src/tolua/tolua_map.c	(revision 3126)
+++ code/branches/pch/src/tolua/tolua_map.c	(revision 3127)
@@ -390,5 +390,5 @@
 	* It maps 'const type' as being also a 'type'
 */
-TOLUA_API void tolua_usertype (lua_State* L, char* type)
+TOLUA_API void tolua_usertype (lua_State* L, const char* type)
 {
  char ctype[128] = "const ";
@@ -404,5 +404,5 @@
 	* It pushes the module (or class) table on the stack
 */
-TOLUA_API void tolua_beginmodule (lua_State* L, char* name)
+TOLUA_API void tolua_beginmodule (lua_State* L, const char* name)
 {
 	if (name)
@@ -427,5 +427,5 @@
 */
 #if 1
-TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
+TOLUA_API void tolua_module (lua_State* L, const char* name, int hasvar)
 {
 	if (name)
@@ -463,5 +463,5 @@
 }
 #else
-TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
+TOLUA_API void tolua_module (lua_State* L, const char* name, int hasvar)
 {
 	if (name)
@@ -519,5 +519,5 @@
 	* It maps a C class, setting the appropriate inheritance and super classes.
 */
-TOLUA_API void tolua_cclass (lua_State* L, char* lname, char* name, char* base, lua_CFunction col)
+TOLUA_API void tolua_cclass (lua_State* L, const char* lname, const char* name, const char* base, lua_CFunction col)
 {
 	char cname[128] = "const ";
@@ -578,5 +578,5 @@
 	* It assigns a function into the current module (or class)
 */
-TOLUA_API void tolua_function (lua_State* L, char* name, lua_CFunction func)
+TOLUA_API void tolua_function (lua_State* L, const char* name, lua_CFunction func)
 {
  lua_pushstring(L,name);
@@ -601,5 +601,5 @@
 	* It assigns a constant number into the current module (or class)
 */
-TOLUA_API void tolua_constant (lua_State* L, char* name, double value)
+TOLUA_API void tolua_constant (lua_State* L, const char* name, lua_Number value)
 {
 	lua_pushstring(L,name);
@@ -612,5 +612,5 @@
 	* It assigns a variable into the current module (or class)
 */
-TOLUA_API void tolua_variable (lua_State* L, char* name, lua_CFunction get, lua_CFunction set)
+TOLUA_API void tolua_variable (lua_State* L, const char* name, lua_CFunction get, lua_CFunction set)
 {
 	/* get func */
@@ -664,5 +664,5 @@
 	* It assigns an array into the current module (or class)
 */
-TOLUA_API void tolua_array (lua_State* L, char* name, lua_CFunction get, lua_CFunction set)
+TOLUA_API void tolua_array (lua_State* L, const char* name, lua_CFunction get, lua_CFunction set)
 {
 	lua_pushstring(L,".get");
Index: code/branches/pch/src/tolua/tolua_push.c
===================================================================
--- code/branches/pch/src/tolua/tolua_push.c	(revision 3126)
+++ code/branches/pch/src/tolua/tolua_push.c	(revision 3127)
@@ -28,5 +28,5 @@
 }
 
-TOLUA_API void tolua_pushnumber (lua_State* L, double value)
+TOLUA_API void tolua_pushnumber (lua_State* L, lua_Number value)
 {
  lua_pushnumber(L,value);
@@ -134,5 +134,5 @@
 
 
-TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, double v)
+TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, lua_Number v)
 {
  lua_pushnumber(L,index);
Index: code/branches/pch/src/tolua/tolua_to.c
===================================================================
--- code/branches/pch/src/tolua/tolua_to.c	(revision 3126)
+++ code/branches/pch/src/tolua/tolua_to.c	(revision 3127)
@@ -18,5 +18,5 @@
 #include <stdlib.h>
 
-TOLUA_API double tolua_tonumber (lua_State* L, int narg, double def)
+TOLUA_API lua_Number tolua_tonumber (lua_State* L, int narg, lua_Number def)
 {
  return lua_gettop(L)<abs(narg) ? def : lua_tonumber(L,narg);
@@ -72,5 +72,5 @@
 }
 
-TOLUA_API double tolua_tofieldnumber (lua_State* L, int lo, int index, double def)
+TOLUA_API lua_Number tolua_tofieldnumber (lua_State* L, int lo, int index, lua_Number def)
 {
  double v;
