diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 53c3ab914bb1fbd32713aad149bd431a0b159310..0000000000000000000000000000000000000000
--- a/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-Claude Heiland-Allen
-Frank Barknecht
-Martin Peach
diff --git a/CHANGES b/CHANGES
deleted file mode 100644
index d5fa05570784c4df28458c7d00b55a9b4453f95e..0000000000000000000000000000000000000000
--- a/CHANGES
+++ /dev/null
@@ -1,41 +0,0 @@
-0.6 20110314
-    Martin Peach changed names of externals to pdlua and pdluax and added the source to svn trunk/pd/externals/pdlua
-0.6~svn	2009-09-14
-	Building:   autoconf system uses -fPIC for amd64 compatibility
-
-0.5	2008-06-18
-	Building:   Makefile.static (recommended)
-	Building:   autoconfiscated (for advanced users)
-	Feature:    interaction with [value], see [revalue] and [lexpr]
-	Feature:    interaction with [table], see [ltabdump] and [ltabfill]
-	Feature:    require() looks relative to .pd_lua and .pd_luax files
-	Internal:   support pd >= 0.41 and pd < 0.41 (pd table API change)
-
-0.4	2008-03-26
-	API change: "load $1"--[lua] users must add the file name extension
-	Bug fix:    "load $1"--[lua] works as advertised
-	API change: users must name files "*.pd_lua" instead of "*.lua"
-	API change: users must name files "*.pd_luax" instead of "*.luax"
-	Bug fix:    help patches should be found correctly
-	Examples++: [lurn], [luametro], [lpipe]
-	Internal:   Doxygenated source comments
-	Internal:   fewer leading underscores
-	Internal:   renamed all examples for API change and tested them
-
-0.3	2007-12-02
-	clock support
-	receive support
-	send support
-	support static builds
-
-0.2	2007-09-25
-	renumbered inlets/outlets: now follow Lua 1,2,... conventions
-	fixed all examples for new numbering
-	more and updated documentation
-	opening via Pd's canvas path with obj:dofile(filename)
-	better error reporting
-	lexpr example
-	bugfix in dispatch (in_3_foo doesn't pass "foo" as an arg any more)
-
-0.1	2007-09-24
-	initial release
diff --git a/src/Makefile b/Makefile
similarity index 51%
rename from src/Makefile
rename to Makefile
index 0eeb3870f4935dfe66192f64aa2a7e7468532521..395b691fa23b73da5b86f394b1b3e10c104e665b 100644
--- a/src/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
-## from Pd library template version 1.0.9
-#  http://puredata.info/docs/developer/Makefilepdlua
+## Pd library template version 1.0.14
+# For instructions on how to use this template, see:
+#  http://puredata.info/docs/developer/MakefileTemplate
 LIBRARY_NAME = pdlua
 
 # add your .c source files, one object per file, to the SOURCES
@@ -7,25 +8,33 @@ LIBRARY_NAME = pdlua
 # objects, the matching .tcl file too
 SOURCES = pdlua.c
 
+## the source directory: either 'src/' (if it exists) or '.'
+PDLUA_SRCPATH=$(firstword $(patsubst src/%,src,$(wildcard src/*)) .)
+
 # list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
 # be included automatically
-PDOBJECTS = pd.lua hello.lua hello.pd_lua hello.pd_luax
+PDOBJECTS = $(PDLUA_SRCPATH)/pd.lua $(PDLUA_SRCPATH)/hello.lua $(PDLUA_SRCPATH)/hello.pd_lua $(PDLUA_SRCPATH)/hello.pd_luax
 
 # example patches and related files, in the 'examples' subfolder
-EXAMPLES = examples/*
+EXAMPLES = $(patsubst examples/%,%,$(wildcard examples/*))
 
 # manuals and related files, in the 'manual' subfolder
-MANUAL = doc/*
+MANUAL = $(patsubst doc/%,%,$(wildcard doc/*))
+
 
 # if you want to include any other files in the source and binary tarballs,
 # list them here.  This can be anything from header files, test patches,
 # documentation, etc.  README.txt and LICENSE.txt are required and therefore
 # automatically included
-EXTRA_DIST = nothing
-
-
+EXTRA_DIST =
 
+# unit tests and related files here, in the 'unittests' subfolder
+UNITTESTS = 
 
+VPATH=$(PDLUA_SRCPATH)
+HELPPATCHES= $(PDLUA_SRCPATH)/pdlua-help.pd \
+	$(PDLUA_SRCPATH)/pdluax-help.pd     \
+	$(PDLUA_SRCPATH)/hello-help.pd
 
 #------------------------------------------------------------------------------#
 #
@@ -33,14 +42,13 @@ EXTRA_DIST = nothing
 #
 #------------------------------------------------------------------------------#
 
-# -I"$(PD_INCLUDE)/pd" supports the header location for 0.43
-# Lua setup
-#CFLAGS += -ansi -pedantic -O2 -fPIC -I/usr/include/lua5.1 -I"$(PD_INCLUDE)/pd" -Wall -W -g
-LDFLAGS =  
-#LUACFLAGS = -DPD -DVERSION='"$(LIBRARY_VERSION)"'
-#LUACFLAGS += -fPIC -I"/usr/include/lua5.1" -I"$(PD_INCLUDE)/pd" -g
-LUACFLAGS = -DVERSION='"$(LIBRARY_VERSION)"'
-#LUACFLAGS += -DPD -fPIC -I"/usr/include/lua5.1" -I"$(PD_INCLUDE)/pd" -g
+LIBRARY_META=$(PDLUA_SRCPATH)/$(LIBRARY_NAME)-meta.pd
+
+ALL_CFLAGS = -I"$(PD_INCLUDE)"
+ALL_LDFLAGS =  
+SHARED_LDFLAGS =
+ALL_LIBS = 
+
 
 #------------------------------------------------------------------------------#
 #
@@ -48,11 +56,20 @@ LUACFLAGS = -DVERSION='"$(LIBRARY_VERSION)"'
 #
 #------------------------------------------------------------------------------#
 
+# these can be set from outside without (usually) breaking the build
+CFLAGS = -Wall -W -g
+LDFLAGS =
+LIBS =
+
+LUA_CFLAGS = -I/usr/include/lua
+LUA_LIBS   = -llua
+
 # get library version from meta file
-LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd)
+LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_META))
 
+ALL_CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"'
 
-PD_INCLUDE = $(PD_PATH)/include
+PD_INCLUDE = $(PD_PATH)/include/pd
 # where to install the library, overridden below depending on platform
 prefix = /usr/local
 libdir = $(prefix)/lib
@@ -64,9 +81,9 @@ INSTALL_PROGRAM = $(INSTALL) -p -m 644
 INSTALL_DATA = $(INSTALL) -p -m 644
 INSTALL_DIR     = $(INSTALL) -p -m 755 -d
 
-ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
+ALLSOURCES_ := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
 	         $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows)
-
+ALLSOURCES=$(ALLSOURCES_:%=$(PDLUA_SRCPATH)/%)
 DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION)
 ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION)
 
@@ -76,6 +93,7 @@ ifeq ($(UNAME),Darwin)
   ifeq ($(CPU),arm) # iPhone/iPod Touch
     SOURCES += $(SOURCES_iphoneos)
     EXTENSION = pd_darwin
+    SHARED_EXTENSION = dylib
     OS = iphoneos
     PD_PATH = /Applications/Pd-extended.app/Contents/Resources
     IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
@@ -85,16 +103,16 @@ ifeq ($(UNAME),Darwin)
     ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk
     IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6
     OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer
-	CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS)
-    LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
-    LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit
-    LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
-    LIBS += -lc 
+    ALL_CFLAGS := $(IPHONE_CFLAGS) $(ALL_CFLAGS)
+    ALL_LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
+    SHARED_LDFLAGS += -arch armv6 -dynamiclib -undefined dynamic_lookup $(ISYSROOT)
+    ALL_LIBS += -lc $(LIBS_iphoneos)
     STRIP = strip -x
     DISTBINDIR=$(DISTDIR)-$(OS)
   else # Mac OS X
     SOURCES += $(SOURCES_macosx)
     EXTENSION = pd_darwin
+    SHARED_EXTENSION = dylib
     OS = macosx
     PD_PATH = /Applications/Pd-extended.app/Contents/Resources
     OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast
@@ -102,16 +120,22 @@ ifeq ($(UNAME),Darwin)
     ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
       FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4
     else
-      FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
       SOURCES += $(SOURCES_iphoneos)
+# Starting with Xcode 4.0, the PowerPC compiler is not installed by default
+      ifeq ($(wildcard /usr/llvm-gcc-4.2/libexec/gcc/powerpc*), )
+        FAT_FLAGS = -arch i386 -arch x86_64 -mmacosx-version-min=10.5
+      else
+        FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
+      endif
     endif
-    CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
-    LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib
+    ALL_CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
     # if the 'pd' binary exists, check the linking against it to aid with stripping
-    LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd)
-    LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit
-    LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
-    LIBS += -lc 
+    BUNDLE_LOADER = $(shell test ! -e $(PD_PATH)/bin/pd || echo -bundle_loader $(PD_PATH)/bin/pd)
+    ALL_LDFLAGS += $(FAT_FLAGS) -headerpad_max_install_names -bundle $(BUNDLE_LOADER) \
+	-undefined dynamic_lookup -L/sw/lib
+    SHARED_LDFLAGS += $(FAT_FLAGS) -dynamiclib -undefined dynamic_lookup \
+	-install_name @loader_path/$(SHARED_LIB) -compatibility_version 1 -current_version 1.0
+    ALL_LIBS += -lc $(LIBS_macosx)
     STRIP = strip -x
     DISTBINDIR=$(DISTDIR)-$(OS)
 # install into ~/Library/Pd on Mac OS X since /usr/local isn't used much
@@ -123,22 +147,32 @@ endif
 ifeq ($(UNAME),ANDROID)
   CPU := arm
   SOURCES += $(SOURCES_android)
-  EXTENSION = pd_linux
+  EXTENSION = so
+  SHARED_EXTENSION = so
   OS = android
   PD_PATH = /usr
-  NDK_BASE := /usr/local/android-ndk
-  NDK_PLATFORM_VERSION := 5
-  NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_VERSION)/arch-arm
-  NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]')
-  NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/$(NDK_UNAME)-x86
-  CC := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT)
+  NDK_BASE := /opt/android-ndk
+  NDK_PLATFORM_LEVEL ?= 5
+  NDK_ABI=arm
+  NDK_COMPILER_VERSION = 4.6
+  NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-$(NDK_ABI)
+  NDK_UNAME:=$(shell uname -s | tr '[A-Z]' '[a-z]')
+  ifeq ($(NDK_ABI),x86)
+    HOST = i686-linux-android
+    NDK_TOOLCHAIN = $(NDK_ABI)-$(NDK_COMPILER_VERSION)
+  else
+    HOST = $(NDK_ABI)-linux-androideabi
+    NDK_TOOLCHAIN = $(HOST)-$(NDK_COMPILER_VERSION)
+  endif
+  NDK_TOOLCHAIN_BASE=$(NDK_BASE)/toolchains/$(NDK_TOOLCHAIN)/prebuilt/$(NDK_UNAME)-$(NDK_PROCESSOR)
+  CC := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-gcc --sysroot=$(NDK_SYSROOT)
+  LD := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ld
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
   CFLAGS += 
-  LDFLAGS += -Wl,--export-dynamic -shared
-  LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit
-  LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
-  LIBS += -lc
-  STRIP := $(NDK_TOOLCHAIN_BASE)/bin/arm-linux-androideabi-strip \
+  LDFLAGS += -rdynamic -shared
+  SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
+  LIBS += -lc $(LIBS_android)
+  STRIP := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-strip) \
 	--strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -146,14 +180,14 @@ ifeq ($(UNAME),Linux)
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_linux)
   EXTENSION = pd_linux
+  SHARED_EXTENSION = so
   OS = linux
   PD_PATH = /usr
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -fPIC -threepic
-  LDFLAGS += -Wl,--export-dynamic  -shared -fPIC
-  LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit
-  LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
-  LIBS += -lc
+  ALL_CFLAGS += -fPIC
+  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
+  SHARED_LDFLAGS += -Wl,-soname,$(SHARED_LIB) -shared
+  ALL_LIBS += -lc $(LIBS_linux)
   STRIP = strip --strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -162,14 +196,14 @@ ifeq ($(UNAME),GNU)
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_linux)
   EXTENSION = pd_linux
+  SHARED_EXTENSION = so
   OS = linux
   PD_PATH = /usr
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -fPIC
-  LDFLAGS += -Wl,--export-dynamic  -shared -fPIC
-  LIBS += -lc
-  LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit
-  LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
+  ALL_CFLAGS += -fPIC
+  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
+  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
+  ALL_LIBS += -lc $(LIBS_linux)
   STRIP = strip --strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -178,14 +212,14 @@ ifeq ($(UNAME),GNU/kFreeBSD)
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_linux)
   EXTENSION = pd_linux
+  SHARED_EXTENSION = so
   OS = linux
   PD_PATH = /usr
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -fPIC
-  LDFLAGS += -Wl,--export-dynamic  -shared -fPIC
-  LIBS += -lc
-  LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit
-  LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
+  ALL_CFLAGS += -fPIC
+  ALL_LDFLAGS += -rdynamic -shared -fPIC -Wl,-rpath,"\$$ORIGIN",--enable-new-dtags
+  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
+  ALL_LIBS += -lc $(LIBS_linux)
   STRIP = strip --strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
 endif
@@ -193,14 +227,14 @@ ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME)))
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_cygwin)
   EXTENSION = dll
+  SHARED_EXTENSION = dll
   OS = cygwin
-  PD_PATH = $(cygpath $(PROGRAMFILES))/pd
+  PD_PATH = $(shell cygpath $$PROGRAMFILES)/pd
   OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
-  CFLAGS += 
-  LDFLAGS += -Wl,--export-dynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
-  LUACFLAGS += -I/usr/include/lua # lua is named differently on every platform, check this and change it to fit
-  LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
-  LIBS += -lc -lpd
+  ALL_CFLAGS += 
+  ALL_LDFLAGS += -rdynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
+  SHARED_LDFLAGS += -shared -Wl,-soname,$(SHARED_LIB)
+  ALL_LIBS += -lc -lpd $(LIBS_cygwin)
   STRIP = strip --strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)
 endif
@@ -208,14 +242,17 @@ ifeq (MINGW,$(findstring MINGW,$(UNAME)))
   CPU := $(shell uname -m)
   SOURCES += $(SOURCES_windows)
   EXTENSION = dll
+  SHARED_EXTENSION = dll
   OS = windows
-  PD_PATH = $(shell cd "$(PROGRAMFILES)"/pd && pwd)
+  PD_PATH = $(shell cd "$$PROGRAMFILES/pd" && pwd)
+  # MinGW doesn't seem to include cc so force gcc
+  CC=gcc
   OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
-  CFLAGS += -mms-bitfields
-  LDFLAGS += -s -shared -Wl,--enable-auto-import
-  LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" -lpd -lwsock32 -lkernel32 -luser32 -lgdi32
-  LUACFLAGS += -I/usr/local/include # lua is named differently on every platform, check this and change it to fit
-  LIBS += -llua  # lua is named differently on every platform, check this and change it to fit
+  ALL_CFLAGS += -mms-bitfields
+  ALL_LDFLAGS += -s -shared -Wl,--enable-auto-import
+  SHARED_LDFLAGS += -shared
+  ALL_LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" \
+	-lpd -lwsock32 -lkernel32 -luser32 -lgdi32 -liberty $(LIBS_windows)
   STRIP = strip --strip-unneeded -R .note -R .comment
   DISTBINDIR=$(DISTDIR)-$(OS)
 endif
@@ -223,52 +260,60 @@ endif
 # in case somebody manually set the HELPPATCHES above
 HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd)
 
-#CFLAGS += $(OPT_CFLAGS)
-#CFLAGS += $(LUACFLAGS)
+ALL_CFLAGS := $(CPPFLAGS) $(ALL_CFLAGS) $(CFLAGS) $(LUA_CFLAGS) $(OPT_CFLAGS)
+ALL_LDFLAGS := $(LDFLAGS) $(LUA_LDFLAGS) $(ALL_LDFLAGS)
+ALL_LIBS := $(LIBS) $(LUA_LIBS) $(ALL_LIBS)
+
+SHARED_SOURCE ?= $(wildcard lib$(LIBRARY_NAME).c)
+SHARED_HEADER ?= $(shell test ! -e $(LIBRARY_NAME).h || echo $(LIBRARY_NAME).h)
+SHARED_LIB ?= $(SHARED_SOURCE:.c=.$(SHARED_EXTENSION))
+SHARED_TCL_LIB = $(wildcard lib$(LIBRARY_NAME).tcl)
 
-.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean dist etags $(LIBRARY_NAME)
+.PHONY = install libdir_install single_install install-doc install-examples install-manual install-unittests clean distclean dist etags $(LIBRARY_NAME) TAGS_PD TAGS_SOURCES
 
-all: $(SOURCES:.c=.$(EXTENSION))
+all: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB)
 
 %.o: %.c
-	@echo "compiling $(LIBRARY_NAME) version $(LIBRARY_VERSION)"
-	@echo "cflags are $(CFLAGS)"
-	@echo "optcflags are $(OPT_CFLAGS)"
-	@echo "luacflags are $(LUACFLAGS)"
-	@echo "ldflags are $(LDFLAGS)"
-	@echo "libs are $(LIBS)"
-	$(CC) $(CFLAGS) $(OPT_CFLAGS) $(LUACFLAGS) -o "$*.o" -c "$*.c"
-
-%.$(EXTENSION): %.o
-	@echo "linking $(LIBRARY_NAME) with $(LIBS)"
-	$(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o"  $(LIBS)
-	chmod a-x "$*.$(EXTENSION)"
+	$(CC) $(ALL_CFLAGS) -o $@ -c $<
+
+%.$(EXTENSION): %.o $(SHARED_LIB)
+	$(CC) $(ALL_LDFLAGS) -o $@ $^ $(ALL_LIBS)
+	chmod a-x $@
 
 # this links everything into a single binary file
-$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
-	$(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS)
-	chmod a-x $(LIBRARY_NAME).$(EXTENSION)
+$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(SHARED_SOURCE:.c=.o)
+	$(CC) $(ALL_LDFLAGS) -o $@.$(EXTENSION) $^ $(ALL_LIBS)
+	chmod a-x $@.$(EXTENSION)
+
+$(SHARED_LIB): $(SHARED_SOURCE:.c=.o)
+	$(CC) $(SHARED_LDFLAGS) -o $@ $^ $(ALL_LIBS)
 
 install: libdir_install
 
 # The meta and help files are explicitly installed to make sure they are
 # actually there.  Those files are not optional, then need to be there.
-libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-examples install-manual
+libdir_install: $(SOURCES:.c=.$(EXTENSION)) $(SHARED_LIB) install-doc install-examples install-manual install-unittests
 	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \
+	$(INSTALL_DATA) $(LIBRARY_META) \
 		$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
 	test -z "$(strip $(SOURCES))" || (\
 		$(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \
 		$(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION))))
-	test -z "$(strip $(shell ls $(SOURCES:.c=.tcl)))" || \
-		$(INSTALL_DATA) $(shell ls $(SOURCES:.c=.tcl)) \
+	test -z "$(strip $(SHARED_LIB))" || \
+		$(INSTALL_DATA) $(SHARED_LIB) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(wildcard $(SOURCES:.c=.tcl)))" || \
+		$(INSTALL_DATA) $(wildcard $(SOURCES:.c=.tcl)) \
 			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
 	test -z "$(strip $(PDOBJECTS))" || \
 		$(INSTALL_DATA) $(PDOBJECTS) \
 			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+	test -z "$(strip $(SHARED_TCL_LIB))" || \
+		$(INSTALL_DATA) $(SHARED_TCL_LIB) \
+			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
 
 # install library linked as single binary
-single_install: $(LIBRARY_NAME) install-doc install-exec
+single_install: $(LIBRARY_NAME) install-doc install-examples install-manual install-unittests
 	$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
 	$(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
 	$(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
@@ -278,8 +323,8 @@ install-doc:
 	test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \
 		$(INSTALL_DATA) $(HELPPATCHES) \
 			$(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
-	$(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt
-	$(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt
+	$(INSTALL_DATA) README $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt
+	$(INSTALL_DATA) COPYING $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt
 
 install-examples:
 	test -z "$(strip $(EXAMPLES))" || \
@@ -290,17 +335,24 @@ install-examples:
 
 install-manual:
 	test -z "$(strip $(MANUAL))" || \
-		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \
+		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/doc && \
 		for file in $(MANUAL); do \
-			$(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \
+			$(INSTALL_DATA) doc/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/doc; \
 		done
 
+install-unittests:
+	test -z "$(strip $(UNITTESTS))" || \
+		$(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests && \
+		for file in $(UNITTESTS); do \
+			$(INSTALL_DATA) unittests/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/unittests; \
+		done
 
 clean:
-	-rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o)
+	-rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) $(SHARED_SOURCE:.c=.o)
 	-rm -f -- $(SOURCES:.c=.$(EXTENSION))
 	-rm -f -- $(LIBRARY_NAME).o
 	-rm -f -- $(LIBRARY_NAME).$(EXTENSION)
+	-rm -f -- $(SHARED_LIB)
 
 distclean: clean
 	-rm -f -- $(DISTBINDIR).tar.gz
@@ -315,8 +367,8 @@ $(DISTBINDIR):
 	$(INSTALL_DIR) $(DISTBINDIR)
 
 libdir: all $(DISTBINDIR)
-	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTBINDIR)
-	$(INSTALL_DATA) $(SOURCES)  $(DISTBINDIR)
+	$(INSTALL_DATA) $(LIBRARY_META)  $(DISTBINDIR)
+	$(INSTALL_DATA) $(ALLSOURCES) $(SHARED_SOURCE) $(SHARED_HEADER) $(DISTBINDIR)
 	$(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR)
 	test -z "$(strip $(EXTRA_DIST))" || \
 		$(INSTALL_DATA) $(EXTRA_DIST)    $(DISTBINDIR)
@@ -330,13 +382,21 @@ $(ORIGDIR):
 
 dist: $(DISTDIR)
 	$(INSTALL_DATA) Makefile  $(DISTDIR)
-	$(INSTALL_DATA) README.txt $(DISTDIR)
-	$(INSTALL_DATA) LICENSE.txt $(DISTDIR)
-	$(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd  $(DISTDIR)
+	$(INSTALL_DATA) README $(DISTDIR)
+	$(INSTALL_DATA) COPYING $(DISTDIR)
+	$(INSTALL_DATA) $(LIBRARY_META) $(DISTDIR)
 	test -z "$(strip $(ALLSOURCES))" || \
 		$(INSTALL_DATA) $(ALLSOURCES)  $(DISTDIR)
-	test -z "$(strip $(shell ls $(ALLSOURCES:.c=.tcl)))" || \
-		$(INSTALL_DATA) $(shell ls $(ALLSOURCES:.c=.tcl))  $(DISTDIR)
+	test -z "$(strip $(wildcard $(ALLSOURCES:.c=.tcl)))" || \
+		$(INSTALL_DATA) $(wildcard $(ALLSOURCES:.c=.tcl))  $(DISTDIR)
+	test -z "$(strip $(wildcard $(LIBRARY_NAME).c))" || \
+		$(INSTALL_DATA) $(LIBRARY_NAME).c  $(DISTDIR)
+	test -z "$(strip $(SHARED_HEADER))" || \
+		$(INSTALL_DATA) $(SHARED_HEADER)  $(DISTDIR)
+	test -z "$(strip $(SHARED_SOURCE))" || \
+		$(INSTALL_DATA) $(SHARED_SOURCE)  $(DISTDIR)
+	test -z "$(strip $(SHARED_TCL_LIB))" || \
+		$(INSTALL_DATA) $(SHARED_TCL_LIB)  $(DISTDIR)
 	test -z "$(strip $(PDOBJECTS))" || \
 		$(INSTALL_DATA) $(PDOBJECTS)  $(DISTDIR)
 	test -z "$(strip $(HELPPATCHES))" || \
@@ -349,9 +409,14 @@ dist: $(DISTDIR)
 			$(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \
 		done
 	test -z "$(strip $(MANUAL))" || \
-		$(INSTALL_DIR) $(DISTDIR)/manual && \
+		$(INSTALL_DIR) $(DISTDIR)/doc && \
 		for file in $(MANUAL); do \
-			$(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \
+			$(INSTALL_DATA) doc/$$file $(DISTDIR)/doc; \
+		done
+	test -z "$(strip $(UNITTESTS))" || \
+		$(INSTALL_DIR) $(DISTDIR)/unittests && \
+		for file in $(UNITTESTS); do \
+			$(INSTALL_DATA) unittests/$$file $(DISTDIR)/unittests; \
 		done
 	tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR)
 
@@ -365,23 +430,49 @@ dpkg-source:
 	rm -rf -- $(DISTDIR) $(ORIGDIR)
 	cd .. && dpkg-source -b $(LIBRARY_NAME)
 
-etags:
-	etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h
+etags: TAGS
+
+TAGS_PD: $(wildcard $(PD_INCLUDE)/*.h)
+	etags $^
+TAGS_SOURCES: $(SOURCES) $(SHARED_SOURCE) $(SHARED_HEADER)
+	etags -a $^
+
+TAGS: TAGS_PD TAGS_SOURCES
+	etags -a *.h
+	etags -a --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl
 
 showsetup:
+	@echo "CC: $(CC)"
 	@echo "CFLAGS: $(CFLAGS)"
 	@echo "LDFLAGS: $(LDFLAGS)"
 	@echo "LIBS: $(LIBS)"
+	@echo "ALL_CFLAGS: $(ALL_CFLAGS)"
+	@echo "ALL_LDFLAGS: $(ALL_LDFLAGS)"
+	@echo "ALL_LIBS: $(ALL_LIBS)"
 	@echo "PD_INCLUDE: $(PD_INCLUDE)"
 	@echo "PD_PATH: $(PD_PATH)"
 	@echo "objectsdir: $(objectsdir)"
 	@echo "LIBRARY_NAME: $(LIBRARY_NAME)"
 	@echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
 	@echo "SOURCES: $(SOURCES)"
+	@echo "SHARED_HEADER: $(SHARED_HEADER)"
+	@echo "SHARED_SOURCE: $(SHARED_SOURCE)"
+	@echo "SHARED_LIB: $(SHARED_LIB)"
+	@echo "SHARED_TCL_LIB: $(SHARED_TCL_LIB)"
 	@echo "PDOBJECTS: $(PDOBJECTS)"
 	@echo "ALLSOURCES: $(ALLSOURCES)"
+	@echo "ALLSOURCES TCL: $(wildcard $(ALLSOURCES:.c=.tcl))"
 	@echo "UNAME: $(UNAME)"
 	@echo "CPU: $(CPU)"
+	@echo "OS: $(OS)"
 	@echo "pkglibdir: $(pkglibdir)"
 	@echo "DISTDIR: $(DISTDIR)"
 	@echo "ORIGDIR: $(ORIGDIR)"
+	@echo "NDK_TOOLCHAIN: $(NDK_TOOLCHAIN)"
+	@echo "NDK_BASE: $(NDK_BASE)"
+	@echo "NDK_SYSROOT: $(NDK_SYSROOT)"
+	@echo ""
+	@echo "EXAMPLES: $(EXAMPLES)"
+	@echo "MANUAL: $(MANUAL)"
+	@echo "EXTRA: $(EXTRA_DIST)"
+	@echo "foo: $(PDLUA_SRCPATH)"
diff --git a/README b/README
index f062239a9b4db934646fc23ebf3eee80fe83bd90..07a8dbda8251df2bb8804e17469573d0a79e30ea 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 pdlua -- a Lua embedding for Pd
-Copyright (C) 2007,2008,2009 Claude Heiland-Allen <claudiusmaximus@goto10.org>
+Copyright (C) 2007,2008,2009 Claude Heiland-Allen <claude@mathr.co.uk>
 
 
 This program is free software; you can redistribute it and/or
diff --git a/TODO b/TODO
deleted file mode 100644
index 5a2d6d14595e093a903a75f4f52ff738c67d9119..0000000000000000000000000000000000000000
--- a/TODO
+++ /dev/null
@@ -1,24 +0,0 @@
-todo
-- fix Pd crash when a Lua error contains '{'
-- documentation
-- install target for make
-- audit require support thoroughly:
-  - make require() support compiled packages
-  - make require() look next to Lua source before containing Pd patch
-- add access to this script's and (containing/parent) Pd patch paths
-- /usr/bin/ld: lua-lua.o: relocation R_X86_64_32 against `.rodata.str1.1'
-  can not be used when making a shared object; recompile with -fPIC
-
-done
-- variable support (like [v foo])
-- table support (like [tabread]/[tabwrite])
-- send support
-- add hook for object (post creation)
-- receive support (preferably multiple receives)
-- clock support
-- audit possible bugs relating to self.f = f(self, ...) misuse
-- write docs on foo.lua vs foo.luax
-- change inlet/outlet numbering to start from 1 instead of 0
-- add pd.dofile(file) that searches via Pd's path (actually obj:dofile(file))
-- write docs implementation (eg foo._bar => internal, etc)
-- add more features to lexpr
diff --git a/doc/pdlua.tex b/doc/pdlua.tex
index becceb91b0139bffd170f369e1df773260908f1f..c37e23d4ad8a6c38799cf298a520b21fe9db70ac 100644
--- a/doc/pdlua.tex
+++ b/doc/pdlua.tex
@@ -3,7 +3,7 @@
 \title{pdlua}
 \author{Claude Heiland-Allen
 \\
-\tt{claudiusmaximus@goto10.org}}
+\tt{claude@mathr.co.uk}}
 
 \begin{document}
 
diff --git a/examples/list-pak.pd_lua b/examples/list-pak.pd_lua
index 1651582d7e88c3d5ee6d8a01ed3fa70ce35bbdee..5964b335415d8ed769e28453f8f8f281585ab883 100644
--- a/examples/list-pak.pd_lua
+++ b/examples/list-pak.pd_lua
@@ -48,7 +48,8 @@ function ListPak:in_n(i, sel, atoms)
         -- insert selector
         self.stored[i] =  sel
     else
-        if table.getn(atoms) > 0 then
+--        if table.getn(atoms) > 0 then
+        if #(atoms) > 0 then
             self.stored[i] =  atoms[1]
         end
     end
diff --git a/examples/list-unpack.pd_lua b/examples/list-unpack.pd_lua
index 08b635c3169e32a1320b75e3f22ba346a46c4798..ebddc4590e6ba084651554fb74ad71f511cdb7f9 100644
--- a/examples/list-unpack.pd_lua
+++ b/examples/list-unpack.pd_lua
@@ -50,7 +50,8 @@ function ListUnpack:in_1(sel, atoms)
         -- also unpack selector of anythings
         table.insert(atoms, 1, sel)
     end
-    local size = math.min(self.outlets, table.getn(atoms))
+--    local size = math.min(self.outlets, table.getn(atoms))
+    local size = math.min(self.outlets, #(atoms))
     for i=size, 1, -1 do
         self:Outlet(i, atoms[i])
     end
diff --git a/examples/peekbag.pd_lua b/examples/peekbag.pd_lua
index 15e4791ca68559baec51745f231f69ad8cac000d..c37a0a39739a55a7b9da8fec8c5e4640493da0e8 100644
--- a/examples/peekbag.pd_lua
+++ b/examples/peekbag.pd_lua
@@ -14,7 +14,8 @@ function PeekBag:in_1_float(f)
     if self.add then
         table.insert(self.bag, f)
     else
-        for i=table.getn(self.bag),1,-1 do
+--        for i=table.getn(self.bag),1,-1 do
+        for i = #(self.bag), 1, -1 do
             if self.bag[i]==f then
                 table.remove(self.bag, i)
                 break
@@ -59,9 +60,11 @@ end
 
 function PeekBag:in_1_aslist()
     -- print all values of array as list
-    if table.getn(self.bag) == 1 then
+--    if table.getn(self.bag) == 1 then
+    if #(self.bag) == 1 then
         self:outlet(1, "float", {self.bag[1]})
-    elseif table.getn(self.bag) > 1 then
+--    elseif table.getn(self.bag) > 1 then
+    elseif #(self.bag) > 1 then
         self:outlet(1, "list", self.bag)
     end
 end
diff --git a/src/hello-help.pd b/hello-help.pd
similarity index 100%
rename from src/hello-help.pd
rename to hello-help.pd
diff --git a/src/hello.lua b/hello.lua
similarity index 100%
rename from src/hello.lua
rename to hello.lua
diff --git a/src/hello.pd_lua b/hello.pd_lua
similarity index 100%
rename from src/hello.pd_lua
rename to hello.pd_lua
diff --git a/src/hello.pd_luax b/hello.pd_luax
similarity index 100%
rename from src/hello.pd_luax
rename to hello.pd_luax
diff --git a/src/pd.lua b/pd.lua
similarity index 99%
rename from src/pd.lua
rename to pd.lua
index 7ad18e94540ffea77732651a14908f58f369164c..fdd1c4a422ad064414d2108f1c4afd7e67e47006 100644
--- a/src/pd.lua
+++ b/pd.lua
@@ -1,6 +1,6 @@
 --[[
 pdlua -- a Lua embedding for Pd
-Copyright (C) 2007,2008 Claude Heiland-Allen <claudiusmaximus@goto10.org>
+Copyright (C) 2007,2008 Claude Heiland-Allen <claude@mathr.co.uk>
 Copyright (C) 2012 Martin Peach martin.peach@sympatico.ca
 
 This program is free software; you can redistribute it and/or
diff --git a/src/pdlua-help.pd b/pdlua-help.pd
similarity index 100%
rename from src/pdlua-help.pd
rename to pdlua-help.pd
diff --git a/src/pdlua-meta.pd b/pdlua-meta.pd
similarity index 84%
rename from src/pdlua-meta.pd
rename to pdlua-meta.pd
index ae8607a7066ffab2650b3abf7abdd4d35d413d01..5100b300959d374a9b5a8ccd02490303db215708 100644
--- a/src/pdlua-meta.pd
+++ b/pdlua-meta.pd
@@ -5,6 +5,6 @@
 #X text 10 50 LICENSE GNU GPL;
 #X text 10 70 DESCRIPTION lua loader for pd;
 #X text 10 90 AUTHOR Claude Heiland-Allen \, Frank Barknecht \, Martin
-Peach;
-#X text 10 110 VERSION 0.6;
+Peach \, IOhannes m zmölnig;
+#X text 10 110 VERSION 0.7.3;
 #X restore 10 20 pd META;
diff --git a/src/pdlua.c b/pdlua.c
similarity index 77%
rename from src/pdlua.c
rename to pdlua.c
index 7feb382f60d71585e6b93178ca26ed546e322b9f..d47a91dce4197567265bbf21157780bd1b84ea50 100644
--- a/src/pdlua.c
+++ b/pdlua.c
@@ -1,1865 +1,1722 @@
-/* This is a version hacked by Martin Peach 20110120 martin.peach@sympatico.ca */
-/* Reformmatted the code and added some debug messages. Changed the name of the class to pdlua */
-/** @file lua.c 
- *  @brief pdlua -- a Lua embedding for Pd.
- *  @author Claude Heiland-Allen <claudiusmaximus@goto10.org>
- *  @date 2008
- *  @version 0.6~svn
- *
- * Copyright (C) 2007,2008 Claude Heiland-Allen <claudiusmaximus@goto10.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- */ 
-
-/* various C stuff, mainly for reading files */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h> // for open
-#include <sys/stat.h> // for open
-#ifdef _MSC_VER
-#include <io.h>
-#include <fcntl.h> // for open
-#define read _read
-#define close _close
-#define ssize_t int
-#define snprintf _snprintf
-#else
-#include <sys/fcntl.h> // for open
-#include <unistd.h>
-#endif
-/* we use Lua */
-#include <lua.h>
-#include <lauxlib.h>
-#include <lualib.h>
-
-/* we use Pd */
-#include "m_pd.h"
-#include "s_stuff.h" // for sys_register_loader()
-#include "m_imp.h" // for struct _class
-/* BAD: support for Pd < 0.41 */
-
-#if PD_MAJOR_VERSION == 0
-# if PD_MINOR_VERSION >= 41
-#  define PDLUA_PD41
-/* use new garray support that is 64-bit safe */
-#  define PDLUA_ARRAYGRAB garray_getfloatwords
-#  define PDLUA_ARRAYTYPE t_word
-#  define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)].w_float)
-# elif PD_MINOR_VERSION >= 40
-#  define PDLUA_PD40
-/* use old garray support, not 64-bit safe */
-#  define PDLUA_ARRAYGRAB garray_getfloatarray
-#  define PDLUA_ARRAYTYPE t_float
-#  define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)])
-# elif PD_MINOR_VERSION >= 39
-#  define PDLUA_PD39
-/* use old garray support, not 64-bit safe */
-#  define PDLUA_ARRAYGRAB garray_getfloatarray
-#  define PDLUA_ARRAYTYPE t_float
-#  define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)])
-# else
-#  error "Pd version is too old, please upgrade"
-# endif
-#else
-# error "Pd version is too new, please file a bug report"
-#endif
-
-/* BAD: end of bad section */
-
-/* If defined, PDLUA_DEBUG lets pdlua post a lot of text */
-//#define PDLUA_DEBUG
-
-/** Global Lua interpreter state, needed in the constructor. */
-static lua_State *L;
-
-/** State for the Lua file reader. */
-typedef struct pdlua_readerdata
-{
-    int         fd; /**< File descriptor to read from. */
-    char        buffer[MAXPDSTRING]; /**< Buffer to read into. */
-} t_pdlua_readerdata;
-
-/** Pd object data. */
-typedef struct pdlua 
-{
-    t_object                pd; /**< We are a Pd object. */
-    int                     inlets; /**< Number of inlets. */
-    struct pdlua_proxyinlet *in; /**< The inlets themselves. */
-    int                     outlets; /**< Number of outlets. */
-    t_outlet                **out; /**< The outlets themselves. */
-    t_canvas                *canvas; /**< The canvas that the object was created on. */
-} t_pdlua;
-
-/** Proxy inlet object data. */
-typedef struct pdlua_proxyinlet
-{
-    t_pd            pd; /**< Minimal Pd object. */
-    struct pdlua    *owner; /**< The owning object to forward inlet messages to. */
-    unsigned int    id; /**< The number of this inlet. */
-} t_pdlua_proxyinlet;
-
-/** Proxy receive object data. */
-typedef struct pdlua_proxyreceive
-{
-    t_pd            pd; /**< Minimal Pd object. */
-    struct pdlua    *owner; /**< The owning object to forward received messages to. */
-    t_symbol        *name; /**< The receive-symbol to bind to. */
-} t_pdlua_proxyreceive;
-
-/** Proxy clock object data. */
-typedef struct pdlua_proxyclock
-{
-    t_pd            pd; /**< Minimal Pd object. */
-    struct pdlua    *owner; /**< Object to forward messages to. */
-    t_clock         *clock; /** Pd clock to use. */
-} t_pdlua_proxyclock;
-/* prototypes*/
-
-static const char *pdlua_reader (lua_State *L, void *rr, size_t *size);
-/** Proxy inlet 'anything' method. */
-static void pdlua_proxyinlet_anything (t_pdlua_proxyinlet *p, t_symbol *s, int argc, t_atom *argv);
-/** Proxy inlet initialization. */
-static void pdlua_proxyinlet_init (t_pdlua_proxyinlet *p, struct pdlua *owner, unsigned int id);
-/** Register the proxy inlet class with Pd. */
-static void pdlua_proxyinlet_setup (void);
-/** Proxy receive 'anything' method. */
-static void pdlua_proxyreceive_anything (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv);
-/** Proxy receive allocation and initialization. */
-static t_pdlua_proxyreceive *pdlua_proxyreceive_new (struct pdlua *owner, t_symbol *name);
-/** Proxy receive cleanup and deallocation. */
-static void pdlua_proxyreceive_free (t_pdlua_proxyreceive *r /**< The proxy receive to free. */);
-/** Register the proxy receive class with Pd. */
-static void pdlua_proxyreceive_setup (void);
-/** Proxy clock 'bang' method. */
-static void pdlua_proxyclock_bang (t_pdlua_proxyclock *c);
-/** Proxy clock allocation and initialization. */
-static t_pdlua_proxyclock *pdlua_proxyclock_new (struct pdlua *owner);
-/** Register the proxy clock class with Pd. */
-static void pdlua_proxyclock_setup (void);
-/** Dump an array of atoms into a Lua table. */
-static void pdlua_pushatomtable (int argc, t_atom *argv);
-/** Pd object constructor. */
-static t_pdlua *pdlua_new (t_symbol *s, int argc, t_atom *argv);
-/** Pd object destructor. */
-static void pdlua_free (t_pdlua *o );
-static void pdlua_stack_dump (lua_State *L);
-/** a handler for the open item in the right-click menu (mrpeach 20111025) */
-/** Here we find the lua code for the object and open it in an editor */
-static void pdlua_menu_open (t_pdlua *o);
-/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */
-static int pdlua_class_new (lua_State *L);
-/** Lua object creation. */
-static int pdlua_object_new (lua_State *L);
-/** Lua object inlet creation. */
-static int pdlua_object_createinlets (lua_State *L);
-/** Lua object outlet creation. */
-static int pdlua_object_createoutlets (lua_State *L);
-/** Lua object receive creation. */
-static int pdlua_receive_new (lua_State *L);
-/** Lua object receive destruction. */
-static int pdlua_receive_free (lua_State *L);
-/** Lua object clock creation. */
-static int pdlua_clock_new (lua_State *L);
-/** Lua proxy clock delay. */
-static int pdlua_clock_delay (lua_State *L);
-/** Lua proxy clock set. */
-static int pdlua_clock_set (lua_State *L);
-/** Lua proxy clock unset. */
-static int pdlua_clock_unset (lua_State *L);
-/** Lua proxy clock destruction. */
-static int pdlua_clock_free (lua_State *L);
-/** Lua object destruction. */
-static int pdlua_object_free (lua_State *L);
-/** Dispatch Pd inlet messages to Lua objects. */
-static void pdlua_dispatch (t_pdlua *o, unsigned int inlet, t_symbol *s, int argc, t_atom *argv);
-/** Dispatch Pd receive messages to Lua objects. */
-static void pdlua_receivedispatch (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv);
-/** Dispatch Pd clock messages to Lua objects. */
-static void pdlua_clockdispatch(t_pdlua_proxyclock *clock);
-/** Convert a Lua table into a Pd atom array. */
-static t_atom *pdlua_popatomtable (lua_State *L, int *count, t_pdlua *o);
-/** Send a message from a Lua object outlet. */
-static int pdlua_outlet (lua_State *L);
-/** Send a message from a Lua object to a Pd receiver. */
-static int pdlua_send (lua_State *L);
-/** Set a [value] object's value. */
-static int pdlua_setvalue (lua_State *L);
-/** Get a [value] object's value. */
-static int pdlua_getvalue (lua_State *L);
-/** Get a [table] object's array. */
-static int pdlua_getarray (lua_State *L);
-/** Read from a [table] object's array. */
-static int pdlua_readarray (lua_State *L);
-/** Write to a [table] object's array. */
-static int pdlua_writearray (lua_State *L);
-/** Redraw a [table] object's graph. */
-static int pdlua_redrawarray (lua_State *L);
-/** Post to Pd's console. */
-static int pdlua_post (lua_State *L);
-/** Report an error from a Lua object to Pd's console. */
-static int pdlua_error (lua_State *L);
-static void pdlua_setrequirepath (lua_State *L, const char *path);
-static void pdlua_clearrequirepath (lua_State *L);
-/** Run a Lua script using Pd's path. */
-static int pdlua_dofile (lua_State *L);
-/** Initialize the pd API for Lua. */
-static void pdlua_init (lua_State *L);
-/** Pd loader hook for loading and executing Lua scripts. */
-static int pdlua_loader (t_canvas *canvas, char *name);
-/** Start the Lua runtime and register our loader hook. */
-#ifdef _WIN32
-__declspec(dllexport)
-#endif 
-void pdlua_setup (void);
-/* end prototypes*/
-
-/* globals */
-struct pdlua_proxyinlet;
-struct pdlua_proxyreceive;
-struct pdlua_proxyclock;
-/** Proxy inlet class pointer. */
-static t_class *pdlua_proxyinlet_class;
-/** Proxy receive class pointer. */
-static t_class *pdlua_proxyreceive_class;
-/** Proxy clock class pointer. */
-static t_class *pdlua_proxyclock_class;
-
-/** Lua file reader callback. */
-static const char *pdlua_reader
-(
-    lua_State *L, /**< Lua interpreter state. */
-    void *rr, /**< Lua file reader state. */
-    size_t *size /**< How much data we have read. */
-)
-{
-    t_pdlua_readerdata  *r = rr;
-    ssize_t             s;
-#ifdef PDLUA_DEBUG
-    post("pdlua_reader: fd is %d", r->fd);
-#endif // PDLUA_DEBUG
-    s = read(r->fd, r->buffer, MAXPDSTRING-2);
-#ifdef PDLUA_DEBUG
-    post("pdlua_reader: s is %ld", s);////////
-#endif // PDLUA_DEBUG
-    if (s <= 0)
-    {
-        *size = 0;
-        return NULL;
-    }
-    else
-    {
-        *size = s;
-        return r->buffer;
-    }
-}
-
-/** Proxy inlet 'anything' method. */
-static void pdlua_proxyinlet_anything
-(
-    t_pdlua_proxyinlet  *p, /**< The proxy inlet that received the message. */
-    t_symbol            *s, /**< The message selector. */
-    int                 argc, /**< The message length. */
-    t_atom              *argv /**< The atoms in the message. */
-)
-{
-    pdlua_dispatch(p->owner, p->id, s, argc, argv);
-}
-
-/** Proxy inlet initialization. */
-static void pdlua_proxyinlet_init
-(
-    t_pdlua_proxyinlet  *p, /**< The proxy inlet to initialize. */
-    struct pdlua        *owner, /**< The owning object. */
-    unsigned int        id /**< The inlet number. */
-)
-{
-    p->pd = pdlua_proxyinlet_class;
-    p->owner = owner;
-    p->id = id;
-}
-
-/** Register the proxy inlet class with Pd. */
-static void pdlua_proxyinlet_setup(void)
-{
-    pdlua_proxyinlet_class = class_new(gensym("pdlua proxy inlet"), 0, 0, sizeof(t_pdlua_proxyinlet), 0, 0);
-    class_addanything(pdlua_proxyinlet_class, pdlua_proxyinlet_anything);
-}
-
-/** Proxy receive 'anything' method. */
-static void pdlua_proxyreceive_anything(
-    t_pdlua_proxyreceive    *r, /**< The proxy receive that received the message. */
-    t_symbol                *s, /**< The message selector. */
-    int                     argc, /**< The message length. */
-    t_atom                  *argv /**< The atoms in the message. */
-)
-{
-    pdlua_receivedispatch(r, s, argc, argv);
-}
-
-/** Proxy receive allocation and initialization. */
-static t_pdlua_proxyreceive *pdlua_proxyreceive_new
-(
-    struct pdlua    *owner, /**< The owning object. */
-    t_symbol        *name /**< The symbol to bind to. */
-)
-{
-    t_pdlua_proxyreceive *r = malloc(sizeof(t_pdlua_proxyreceive));
-    r->pd = pdlua_proxyreceive_class;
-    r->owner = owner;
-    r->name = name;
-    pd_bind(&r->pd, r->name);
-    return r;
-}
-
-/** Proxy receive cleanup and deallocation. */
-static void pdlua_proxyreceive_free(t_pdlua_proxyreceive *r /**< The proxy receive to free. */)
-{
-    pd_unbind(&r->pd, r->name);
-    r->pd = NULL;
-    r->owner = NULL;
-    r->name = NULL;
-    free(r);
-}
-
-/** Register the proxy receive class with Pd. */
-static void pdlua_proxyreceive_setup()
-{
-    pdlua_proxyreceive_class = class_new(gensym("pdlua proxy receive"), 0, 0, sizeof(t_pdlua_proxyreceive), 0, 0);
-    class_addanything(pdlua_proxyreceive_class, pdlua_proxyreceive_anything);
-}
-
-/** Proxy clock 'bang' method. */
-static void pdlua_proxyclock_bang(t_pdlua_proxyclock *c /**< The proxy clock that received the message. */)
-{
-    pdlua_clockdispatch(c);
-}
-
-/** Proxy clock allocation and initialization. */
-static t_pdlua_proxyclock *pdlua_proxyclock_new
-(
-    struct pdlua *owner /**< The object to forward messages to. */
-)
-{
-    t_pdlua_proxyclock *c = malloc(sizeof(t_pdlua_proxyclock));
-    c->pd = pdlua_proxyclock_class;
-    c->owner = owner;
-    c->clock = clock_new(c, (t_method) pdlua_proxyclock_bang);
-    return c;
-}
-
-/** Register the proxy clock class with Pd. */
-static void pdlua_proxyclock_setup(void)
-{
-    pdlua_proxyclock_class = class_new(gensym("pdlua proxy clock"), 0, 0, sizeof(t_pdlua_proxyclock), 0, 0);
-}
-
-/** Dump an array of atoms into a Lua table. */
-static void pdlua_pushatomtable
-(
-    int     argc, /**< The number of atoms in the array. */
-    t_atom  *argv /**< The array of atoms. */
-)
-{
-    int i;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_pushatomtable: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_newtable(L);
-    for (i = 0; i < argc; ++i)
-    {
-        lua_pushnumber(L, i+1);
-        switch (argv[i].a_type)
-        {
-            case A_FLOAT:
-                lua_pushnumber(L, argv[i].a_w.w_float);
-                break;
-            case A_SYMBOL:
-                lua_pushstring(L, argv[i].a_w.w_symbol->s_name);
-                break;
-            case A_POINTER: /* FIXME: check experimentality */
-                lua_pushlightuserdata(L, argv[i].a_w.w_gpointer);
-            break;
-            default:
-                error("lua: zomg weasels!");
-                lua_pushnil(L);
-            break;
-        }
-        lua_settable(L, -3);
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_pushatomtable: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-}
-
-/** Pd object constructor. */
-static t_pdlua *pdlua_new
-(
-    t_symbol    *s, /**< The construction message selector. */
-    int         argc, /**< The construction message atom count. */
-    t_atom      *argv /**< The construction message atoms. */
-)
-{
-    int i;
-#ifdef PDLUA_DEBUG
-    post("pdlua_new: s->s_name is %s", s->s_name);
-#endif // PDLUA_DEBUG
-    for (i = 0; i < argc; ++i)
-    {
-        switch (argv[i].a_type)
-        {
-        case A_FLOAT:
-#ifdef PDLUA_DEBUG
-            post("argv[%d]: %f", i, argv[i].a_w.w_float);
-#endif // PDLUA_DEBUG
-            break;
-        case A_SYMBOL:
-#ifdef PDLUA_DEBUG
-            post("argv[%d]: %s", i, argv[i].a_w.w_symbol->s_name);
-#endif // PDLUA_DEBUG
-            break;
-        default:
-            error("pdlua_new: bad argument type"); // should never happen
-            return NULL;
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_new: start with stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_getglobal(L, "pd");
-    lua_getfield(L, -1, "_constructor");
-    lua_pushstring(L, s->s_name);
-    pdlua_pushatomtable(argc, argv);
-#ifdef PDLUA_DEBUG
-    post("pdlua_new: before lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_pcall(L, 2, 1, 0))
-    {
-        error("pdlua_new: error in constructor for `%s':\n%s", s->s_name, lua_tostring(L, -1));
-        lua_pop(L, 2); /* pop the error string and the global "pd" */
-        return NULL;
-    }
-    else
-    {
-        t_pdlua *object = NULL;
-#ifdef PDLUA_DEBUG
-        post("pdlua_new: done lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-        if (lua_islightuserdata(L, -1))
-        {
-            object = lua_touserdata(L, -1);
-            lua_pop(L, 2);/* pop the userdata and the global "pd" */
-#ifdef PDLUA_DEBUG
-            post("pdlua_new: before returning object %p stack top %d", object, lua_gettop(L));
-#endif // PDLUA_DEBUG
-             return object;
-        }
-        else
-        {
-            lua_pop(L, 2);/* pop the userdata and the global "pd" */
-#ifdef PDLUA_DEBUG
-            post("pdlua_new: done FALSE lua_islightuserdata(L, -1)");
-#endif // PDLUA_DEBUG
-            return NULL;
-        }
-    }
-}
-
-/** Pd object destructor. */
-static void pdlua_free( t_pdlua *o /**< The object to destruct. */)
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_free: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_getglobal(L, "pd");
-    lua_getfield (L, -1, "_destructor");
-    lua_pushlightuserdata(L, o);
-    if (lua_pcall(L, 1, 0, 0))
-    {
-        error("lua: error in destructor:\n%s", lua_tostring(L, -1));
-        lua_pop(L, 1); /* pop the error string */
-    }
-    lua_pop(L, 1); /* pop the global "pd" */
-#ifdef PDLUA_DEBUG
-    post("pdlua_free: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return;
-}
-
-static void pdlua_stack_dump (lua_State *L)
-{
-    int i;
-    int top = lua_gettop(L);
-
-    for (i = 1; i <= top; i++)
-    {  /* repeat for each level */
-        int t = lua_type(L, i);
-        switch (t)
-        {
-            case LUA_TSTRING:  /* strings */
-                printf("`%s'", lua_tostring(L, i));
-                break;
-    
-            case LUA_TBOOLEAN:  /* booleans */
-                printf(lua_toboolean(L, i) ? "true" : "false");
-                break;
-    
-            case LUA_TNUMBER:  /* numbers */
-                printf("%g", lua_tonumber(L, i));
-                break;
-    
-            default:  /* other values */
-                printf("%s", lua_typename(L, t));
-                break;
-        }
-        printf("  ");  /* put a separator */
-    }
-    printf("\n");  /* end the listing */
-}
-
-/** a handler for the open item in the right-click menu (mrpeach 20111025) */
-/** Here we find the lua code for the object and open it in an editor */
-static void pdlua_menu_open(t_pdlua *o)
-{
-    const char  *name;
-    const char  *path;
-    char        pathname[FILENAME_MAX];
-    t_class     *class;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_menu_open stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    /** Get the scriptname of the object */
-    lua_getglobal(L, "pd");
-    lua_getfield(L, -1, "_whoami");
-    lua_pushlightuserdata(L, o);
-    if (lua_pcall(L, 1, 1, 0))
-    {
-        error("lua: error in whoami:\n%s", lua_tostring(L, -1));
-        lua_pop(L, 2); /* pop the error string and the global "pd" */
-        return;
-    }
-    name = luaL_checkstring(L, -1);
-#ifdef PDLUA_DEBUG
-    post("pdlua_menu_open: L is %p, name is %s stack top is %d", L, name, lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (name)
-    {
-        if (name[strlen(name)-1] == 'x')
-        {
-            /* pdluax is a class, the particular file should loadable by name alone, we hope */
-            sprintf(pathname, "%s", name);
-            lua_pop(L, 2); /* pop name and the global "pd" */
-        }
-        else
-        {
-            lua_getglobal(L, "pd");
-            lua_getfield(L, -1, "_get_class");
-            lua_pushlightuserdata(L, o);
-            if (lua_pcall(L, 1, 1, 0))
-            {
-                error("lua: error in get_class:\n%s", lua_tostring(L, -1));
-                lua_pop(L, 4); /* pop the error string, global "pd", name, global "pd"*/
-                return;
-            }
-            class = (t_class *)lua_touserdata(L, -1);
-            path = class->c_externdir->s_name;
-            sprintf(pathname, "%s/%s", path, name);
-            lua_pop(L, 4); /* pop class, global "pd", name, global "pd"*/
-        }
-#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43
-        post("Opening %s for editing", pathname);
-#else
-        logpost(NULL, 3, "Opening %s for editing", pathname);
-#endif
-        sys_vgui("::pd_menucommands::menu_openfile {%s}\n", pathname);
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_menu_open end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-}
-
-/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */
-static int pdlua_class_new(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Class name string.
-  * \par Outputs:
-  * \li \c 1 Pd class pointer.
-  * */
-{
-    const char  *name;
-    t_class     *c;
-
-    name = luaL_checkstring(L, 1);
-#ifdef PDLUA_DEBUG
-    post("pdlua_class_new: L is %p, name is %s stack top is %d", L, name, lua_gettop(L));
-#endif // PDLUA_DEBUG
-    c = class_new(gensym((char *) name), (t_newmethod) pdlua_new,
-        (t_method) pdlua_free, sizeof(t_pdlua), CLASS_NOINLET, A_GIMME, 0);
-
-/* a class with a "menu-open" method will have the "Open" item highlighted in the right-click menu */
-    class_addmethod(c, (t_method)pdlua_menu_open, gensym("menu-open"), A_NULL);/* (mrpeach 20111025) */
-/**/
-
-    lua_pushlightuserdata(L, c);
-#ifdef PDLUA_DEBUG
-    post("pdlua_class_new: end stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 1;
-}
-
-/** Lua object creation. */
-static int pdlua_object_new(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd class pointer.
-  * \par Outputs:
-  * \li \c 2 Pd object pointer.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_new: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_class *c = lua_touserdata(L, 1);
-        if (c)
-        {
-#ifdef PDLUA_DEBUG
-            char *path = c->c_externdir->s_name;
-            post("pdlua_object_new: path is %s", path);
-#endif // PDLUA_DEBUG
-            t_pdlua *o = (t_pdlua *) pd_new(c);
-            if (o)
-            {
-                o->inlets = 0;
-                o->in = NULL;
-                o->outlets = 0;
-                o->out = NULL;
-                o->canvas = canvas_getcurrent();
-                lua_pushlightuserdata(L, o);
-#ifdef PDLUA_DEBUG
-                post("pdlua_object_new: success end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-                return 1;
-            }
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_new: fail end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua object inlet creation. */
-static int pdlua_object_createinlets(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * \li \c 2 Number of inlets.
-  * */
-{
-    int i;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_createinlets: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua *o = lua_touserdata(L, 1);
-        if (o)
-        {
-            o->inlets = luaL_checknumber(L, 2);
-            o->in = malloc(o->inlets * sizeof(t_pdlua_proxyinlet));
-            for (i = 0; i < o->inlets; ++i)
-            {
-                pdlua_proxyinlet_init(&o->in[i], o, i);
-                inlet_new(&o->pd, &o->in[i].pd, 0, 0);
-            }
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_createinlets: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua object outlet creation. */
-static int pdlua_object_createoutlets(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * \li \c 2 Number of outlets.
-  * */
-{
-    int i;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_createoutlets: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua *o = lua_touserdata(L, 1);
-        if (o)
-        {
-            o->outlets = luaL_checknumber(L, 2);
-            if (o->outlets > 0)
-            {
-                o->out = malloc(o->outlets * sizeof(t_outlet *));
-                for (i = 0; i < o->outlets; ++i) o->out[i] = outlet_new(&o->pd, 0);
-            }
-            else o->out = NULL;
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_createoutlets: end stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua object receive creation. */
-static int pdlua_receive_new(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * \li \c 2 Receive name string.
-  * \par Outputs:
-  * \li \c 1 Pd receive pointer.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_receive_new: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua *o = lua_touserdata(L, 1);
-        if (o)
-        {
-            const char *name = luaL_checkstring(L, 2);
-            if (name)
-            {
-                t_pdlua_proxyreceive *r =  pdlua_proxyreceive_new(o, gensym((char *) name)); /* const cast */
-                lua_pushlightuserdata(L, r);
-#ifdef PDLUA_DEBUG
-                post("pdlua_receive_new: success end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-                return 1;
-            }
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_receive_new: fail end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua object receive destruction. */
-static int pdlua_receive_free(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd recieve pointer.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_receive_free: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua_proxyreceive *r = lua_touserdata(L, 1);
-        if (r) pdlua_proxyreceive_free(r);
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_receive_free: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua object clock creation. */
-static int pdlua_clock_new(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * \par Outputs:
-  * \li \c 1 Pd clock pointer.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_new: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua *o = lua_touserdata(L, 1);
-        if (o)
-        {
-            t_pdlua_proxyclock *c =  pdlua_proxyclock_new(o);
-            lua_pushlightuserdata(L, c);
-#ifdef PDLUA_DEBUG
-            post("pdlua_clock_new: success end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-            return 1;
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_new: fail end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua proxy clock delay. */
-static int pdlua_clock_delay(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd clock pointer.
-  * \li \c 2 Number of milliseconds to delay.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_delay: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
-        if (c)
-        {
-            double delaytime = luaL_checknumber(L, 2);
-            clock_delay(c->clock, delaytime);
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_delay: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua proxy clock set. */
-static int pdlua_clock_set(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd clock pointer.
-  * \li \c 2 Number to set the clock.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_set: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
-        if (c)
-        {
-            double systime = luaL_checknumber(L, 2);
-            clock_set(c->clock, systime);
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_set: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua proxy clock unset. */
-static int pdlua_clock_unset(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd clock pointer.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_unset: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
-        if (c) clock_unset(c->clock);
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_unset: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua proxy clock destruction. */
-static int pdlua_clock_free(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd clock pointer.
-  * */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_free: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
-        if (c)
-        {
-            clock_free(c->clock);
-            free(c);
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_clock_free: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Lua object destruction. */
-static int pdlua_object_free(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * */
-{
-    int i;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_free: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        t_pdlua *o = lua_touserdata(L, 1);
-        if (o)
-        {
-            if (o->in) free(o->in);
-            if(o->out)
-            {
-                for (i = 0; i < o->outlets; ++i) outlet_free(o->out[i]);
-                free(o->out);
-                o->out = NULL;
-            }
-        }
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_object_free: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Dispatch Pd inlet messages to Lua objects. */
-static void pdlua_dispatch
-(
-    t_pdlua         *o, /**< The object that received the message. */
-    unsigned int    inlet, /**< The inlet that the message arrived at. */
-    t_symbol        *s, /**< The message selector. */
-    int             argc, /**< The message length. */
-    t_atom          *argv /**< The atoms in the message. */
-)
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_dispatch: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_getglobal(L, "pd");
-    lua_getfield (L, -1, "_dispatcher");
-    lua_pushlightuserdata(L, o);
-    lua_pushnumber(L, inlet + 1); /* C has 0.., Lua has 1.. */
-    lua_pushstring(L, s->s_name);
-    pdlua_pushatomtable(argc, argv);
-    if (lua_pcall(L, 4, 0, 0))
-    {
-        pd_error(o, "lua: error in dispatcher:\n%s", lua_tostring(L, -1));
-        lua_pop(L, 1); /* pop the error string */
-    }
-    lua_pop(L, 1); /* pop the global "pd" */
-#ifdef PDLUA_DEBUG
-    post("pdlua_dispatch: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return;  
-}
-
-/** Dispatch Pd receive messages to Lua objects. */
-static void pdlua_receivedispatch
-(
-    t_pdlua_proxyreceive    *r, /**< The proxy receive that received the message. */
-    t_symbol                *s, /**< The message selector. */
-    int                     argc, /**< The message length. */
-    t_atom                  *argv /**< The atoms in the message. */
-)
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_receivedispatch: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_getglobal(L, "pd");
-    lua_getfield (L, -1, "_receivedispatch");
-    lua_pushlightuserdata(L, r);
-    lua_pushstring(L, s->s_name);
-    pdlua_pushatomtable(argc, argv);
-    if (lua_pcall(L, 3, 0, 0))
-    {
-        pd_error(r->owner, "lua: error in receive dispatcher:\n%s", lua_tostring(L, -1));
-        lua_pop(L, 1); /* pop the error string */
-    }
-    lua_pop(L, 1); /* pop the global "pd" */
-#ifdef PDLUA_DEBUG
-    post("pdlua_receivedispatch: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return;  
-}
-
-/** Dispatch Pd clock messages to Lua objects. */
-static void pdlua_clockdispatch( t_pdlua_proxyclock *clock)
-/**< The proxy clock that received the message. */
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_clockdispatch: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_getglobal(L, "pd");
-    lua_getfield (L, -1, "_clockdispatch");
-    lua_pushlightuserdata(L, clock);
-    if (lua_pcall(L, 1, 0, 0))
-    {
-        pd_error(clock->owner, "lua: error in clock dispatcher:\n%s", lua_tostring(L, -1));
-        lua_pop(L, 1); /* pop the error string */
-    }
-    lua_pop(L, 1); /* pop the global "pd" */
-#ifdef PDLUA_DEBUG
-    post("pdlua_clockdispatch: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return;  
-}
-
-/** Convert a Lua table into a Pd atom array. */
-static t_atom *pdlua_popatomtable
-(
-    lua_State   *L, /**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c -1 Table to convert.
-  * */
-    int         *count, /**< Where to store the array length. */
-    t_pdlua     *o /**< Object reference for error messages. */
-)
-{
-    int         i;
-    int         ok = 1;
-    t_float     f;
-    const char  *s;
-    void        *p;
-    size_t      sl;
-    t_atom      *atoms = NULL;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_popatomtable: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_istable(L, -1))
-    {
-#if LUA_VERSION_NUM	< 502
-        *count = lua_objlen(L, -1);
-#else // 5.2 style
-        *count = lua_rawlen(L, -1);
-#endif // LUA_VERSION_NUM	< 502
-        if (*count > 0) atoms = malloc(*count * sizeof(t_atom));
-        i = 0;
-        lua_pushnil(L);
-        while (lua_next(L, -2) != 0)
-        {
-            if (i == *count)
-            {
-                pd_error(o, "lua: error: too many table elements");
-                ok = 0;
-                break;
-            }
-            switch (lua_type(L, -1))
-            {
-                case (LUA_TNUMBER):
-                    f = lua_tonumber(L, -1);
-                    SETFLOAT(&atoms[i], f);
-                    break;
-                case (LUA_TSTRING):
-                    s = lua_tolstring(L, -1, &sl);
-                    if (s)
-                    {
-                        if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)");
-                        SETSYMBOL(&atoms[i], gensym((char *) s));
-                    }
-                    else
-                    {
-                        pd_error(o, "lua: error: null string in table");
-                        ok = 0;
-                    }
-                    break;
-                case (LUA_TLIGHTUSERDATA): /* FIXME: check experimentality */
-                    p = lua_touserdata(L, -1);
-                    SETPOINTER(&atoms[i], p);
-                    break;
-                default:
-                    pd_error(o, "lua: error: table element must be number or string or pointer");
-                    ok = 0;
-                    break;
-            }
-            lua_pop(L, 1);
-            ++i;
-        }
-        if (i != *count)
-        {
-            pd_error(o, "lua: error: too few table elements");
-            ok = 0;
-        }
-    }
-    else 
-    {
-        pd_error(o, "lua: error: not a table");
-        ok = 0;
-    }
-    lua_pop(L, 1);
-#ifdef PDLUA_DEBUG
-    post("pdlua_popatomtable: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (ok) return atoms;
-    if (atoms) free(atoms);
-    return NULL;
-}
-
-/** Send a message from a Lua object outlet. */
-static int pdlua_outlet(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * \li \c 2 Outlet number.
-  * \li \c 3 Message selector string.
-  * \li \c 4 Message atom table.
-  * */
-{
-    t_pdlua         *o;
-    int             out;
-    size_t          sl;
-    const char      *s;
-    t_symbol        *sym;
-    int             count;
-    t_atom          *atoms;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_outlet: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        o = lua_touserdata(L, 1);
-        if (o) 
-        {
-            if (lua_isnumber(L, 2)) out = lua_tonumber(L, 2) - 1; /* C has 0.., Lua has 1.. */
-            else
-            {
-                pd_error(o, "lua: error: outlet must be a number");
-                lua_pop(L, 4); /* pop all the arguments */
-                return 0;
-            }
-            if (0 <= out && out < o->outlets) 
-            {
-                if (lua_isstring(L, 3)) 
-                {
-                    s = lua_tolstring(L, 3, &sl);
-                    sym = gensym((char *) s); /* const cast */
-                    if (s)
-                    {
-                        if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)");
-                        lua_pushvalue(L, 4);
-                        atoms = pdlua_popatomtable(L, &count, o);
-                        if (count == 0 || atoms) outlet_anything(o->out[out], sym, count, atoms);
-                        else pd_error(o, "lua: error: no atoms??");
-                        if (atoms) 
-                        {
-                            free(atoms);
-                            lua_pop(L, 4); /* pop all the arguments */
-                            return 0;
-                        }
-                    }
-                    else pd_error(o, "lua: error: null selector");
-                }
-                else pd_error(o, "lua: error: selector must be a string");
-            }
-            else pd_error(o, "lua: error: outlet out of range");
-        }
-        else error("lua: error: no object to outlet from");
-    }
-    else error("lua: error: bad arguments to outlet");
-    lua_pop(L, 4); /* pop all the arguments */
-#ifdef PDLUA_DEBUG
-    post("pdlua_outlet: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Send a message from a Lua object to a Pd receiver. */
-static int pdlua_send(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Receiver string.
-  * \li \c 2 Message selector string.
-  * \li \c 3 Message atom table.
-  * */
-
-{
-    size_t          receivenamel;
-    const char      *receivename;
-    t_symbol        *receivesym;
-    size_t          selnamel;
-    const char      *selname;
-    t_symbol        *selsym;
-    int             count;
-    t_atom          *atoms;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_send: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_isstring(L, 1)) 
-    {
-        receivename = lua_tolstring(L, 1, &receivenamel);
-        receivesym = gensym((char *) receivename); /* const cast */
-        if (receivesym) 
-        {
-            if (strlen(receivename) != receivenamel) error("lua: warning: symbol munged (contains \\0 in body)");
-            if (lua_isstring(L, 2)) 
-            {
-                selname = lua_tolstring(L, 2, &selnamel);
-                selsym = gensym((char *) selname); /* const cast */
-                if (selsym)
-                {
-                    if (strlen(selname) != selnamel) error("lua: warning: symbol munged (contains \\0 in body)");
-                    lua_pushvalue(L, 3);
-                    atoms = pdlua_popatomtable(L, &count, NULL);
-                    if ((count == 0 || atoms) && (receivesym->s_thing)) typedmess(receivesym->s_thing, selsym, count, atoms);
-                    else error("lua: error: no atoms??");
-                    if (atoms) 
-                    {
-                        free(atoms);
-#ifdef PDLUA_DEBUG
-                        post("pdlua_send: success end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-                        return 0;
-                    }
-                }
-                else error("lua: error: null selector");
-            }
-            else error("lua: error: selector must be a string");
-        }
-        else error("lua: error: null receive name");
-    }
-    else error("lua: error: receive name must be string");
-#ifdef PDLUA_DEBUG
-    post("pdlua_send: fail end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Set a [value] object's value. */
-static int pdlua_setvalue(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Value name string.
-  * \li \c 2 Value number.
-  * \par Outputs:
-  * \li \c 1 success (usually depends on a [value] existing or not).
-  */
-{
-    const char  *str = luaL_checkstring(L, 1);
-    t_float     val = luaL_checknumber(L, 2);
-    int         err = value_setfloat(gensym(str), val);
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_setvalue: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_pushboolean(L, !err);
-#ifdef PDLUA_DEBUG
-    post("pdlua_setvalue: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 1;
-}
-
-/** Get a [value] object's value. */
-static int pdlua_getvalue(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Value name string.
-  * \par Outputs:
-  * \li \c 1 Value number, or nil for failure.
-  * */
-{
-    const char  *str = luaL_checkstring(L, 1);
-    t_float     val;
-    int         err = value_getfloat(gensym(str), &val);
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_getvalue: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (!err) lua_pushnumber(L, val);
-    else lua_pushnil(L);
-#ifdef PDLUA_DEBUG
-    post("pdlua_getvalue: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 1;
-}
-
-/** Get a [table] object's array. */
-static int pdlua_getarray(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Table name string.
-  * \par Outputs:
-  * \li \c 1 Table length, or < 0 for failure.
-  * \li \c 2 Table pointer, or nil for failure.
-  * */
-{
-    t_garray        *a;
-    int             n;
-    PDLUA_ARRAYTYPE *v;
-    const char      *str = luaL_checkstring(L, 1);
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_getarray: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (!(a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) 
-    {
-        lua_pushnumber(L, -1);
-#ifdef PDLUA_DEBUG
-        post("pdlua_getarray: end 1. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-        return 1;
-    }
-    else if (!PDLUA_ARRAYGRAB(a, &n, &v)) 
-    {
-        lua_pushnumber(L, -2);
-#ifdef PDLUA_DEBUG
-        post("pdlua_getarray: end 2. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-        return 1;
-    }
-    else 
-    {
-        lua_pushnumber(L, n);
-        lua_pushlightuserdata(L, v);
-#ifdef PDLUA_DEBUG
-        post("pdlua_getarray: end 3. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-        return 2;
-    }
-}
-
-/** Read from a [table] object's array. */
-static int pdlua_readarray(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Table length number.
-  * \li \c 2 Table array pointer.
-  * \li \c 3 Table index number.
-  * \par Outputs:
-  * \li \c 1 Table element value, or nil for index out of range.
-  * */
-{
-    int             n = luaL_checknumber(L, 1);
-    PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL;
-    int             i = luaL_checknumber(L, 3);
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_readarray: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (0 <= i && i < n && v) 
-    {
-        lua_pushnumber(L, PDLUA_ARRAYELEM(v, i));
-#ifdef PDLUA_DEBUG
-        post("pdlua_readarray: end 1. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-        return 1;
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_readarray: end 2. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Write to a [table] object's array. */
-static int pdlua_writearray(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Table length number.
-  * \li \c 2 Table array pointer.
-  * \li \c 3 Table index number.
-  * \li \c 4 Table element value number.
-  * */
-{
-    int                 n = luaL_checknumber(L, 1);
-    PDLUA_ARRAYTYPE     *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL;
-    int                 i = luaL_checknumber(L, 3);
-    t_float             x = luaL_checknumber(L, 4);
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_writearray: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (0 <= i && i < n && v) PDLUA_ARRAYELEM(v, i) = x;
-#ifdef PDLUA_DEBUG
-    post("pdlua_writearray: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Redraw a [table] object's graph. */
-static int pdlua_redrawarray(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Table name string.
-  * */
-{
-    t_garray    *a;
-    const char  *str = luaL_checkstring(L, 1);
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_redrawarray: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if ((a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) garray_redraw(a);
-#ifdef PDLUA_DEBUG
-    post("pdlua_redrawarray: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Post to Pd's console. */
-static int pdlua_post(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Message string.
-  * */
-{
-    const char *str = luaL_checkstring(L, 1);
-#ifdef PDLUA_DEBUG
-    post("pdlua_post: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    post("%s", str);
-#ifdef PDLUA_DEBUG
-    post("pdlua_post: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Report an error from a Lua object to Pd's console. */
-static int pdlua_error(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * \li \c 2 Message string.
-  * */
-{
-    t_pdlua     *o;
-
-
-    const char  *s;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_error: stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (lua_islightuserdata(L, 1))
-    {
-        o = lua_touserdata(L, 1);
-        if (o)
-        {
-            s = luaL_checkstring(L, 2);
-            if (s) pd_error(o, "%s", s);
-            else pd_error(o, "lua: error: null string in error function");
-        }
-        else error("lua: error: null object in error function");
-    }
-    else error("lua: error: bad arguments to error function");
-#ifdef PDLUA_DEBUG
-    post("pdlua_error: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-static void pdlua_setrequirepath
-( /* FIXME: documentation (is this of any use at all?) */
-    lua_State   *L,
-    const char  *path
-)
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_setrequirepath: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_getglobal(L, "pd");
-    lua_pushstring(L, "_setrequirepath");
-    lua_gettable(L, -2);
-    lua_pushstring(L, path);
-    if (lua_pcall(L, 1, 0, 0) != 0)
-    {
-        error("lua: internal error in `pd._setrequirepath': %s", lua_tostring(L, -1));
-        lua_pop(L, 1);
-    }
-    lua_pop(L, 1);
-#ifdef PDLUA_DEBUG
-    post("pdlua_setrequirepath: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-}
-
-static void pdlua_clearrequirepath
-( /* FIXME: documentation (is this of any use at all?) */
-    lua_State *L
-)
-{
-#ifdef PDLUA_DEBUG
-    post("pdlua_clearrequirepath: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    lua_getglobal(L, "pd");
-    lua_pushstring(L, "_clearrequirepath");
-    lua_gettable(L, -2);
-    if (lua_pcall(L, 0, 0, 0) != 0)
-    {
-        error("lua: internal error in `pd._clearrequirepath': %s", lua_tostring(L, -1));
-        lua_pop(L, 1);
-    }
-    lua_pop(L, 1);
-#ifdef PDLUA_DEBUG
-    post("pdlua_clearrequirepath: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-}
-
-/** Run a Lua script using Pd's path. */
-static int pdlua_dofile(lua_State *L)
-/**< Lua interpreter state.
-  * \par Inputs:
-  * \li \c 1 Pd object pointer.
-  * \li \c 2 Filename string.
-  * \par Outputs:
-  * \li \c * Determined by the script.
-  * */
-{
-    char                buf[MAXPDSTRING];
-    char                *ptr;
-    t_pdlua_readerdata  reader;
-    int                 fd;
-    int                 n;
-    const char          *filename;
-    t_pdlua             *o;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_dofile: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    n = lua_gettop(L);
-    if (lua_islightuserdata(L, 1))
-    {
-        o = lua_touserdata(L, 1);
-        if (o)
-        {
-            filename = luaL_optstring(L, 2, NULL);
-            fd = canvas_open(o->canvas, filename, "", buf, &ptr, MAXPDSTRING, 1);
-            if (fd >= 0)
-            {
-#ifdef PDLUA_DEBUG
-                post("pdlua_dofile path is %s", buf);
-#endif // PDLUA_DEBUG
-                //pdlua_setpathname(o, buf);/* change the scriptname to include its path */
-                pdlua_setrequirepath(L, buf);
-                reader.fd = fd;
-#if LUA_VERSION_NUM	< 502
-                if (lua_load(L, pdlua_reader, &reader, filename))
-#else // 5.2 style
-                if (lua_load(L, pdlua_reader, &reader, filename, NULL))
-#endif // LUA_VERSION_NUM	< 502
-                {
-                    close(fd);
-                    pdlua_clearrequirepath(L);
-                    lua_error(L);
-                }
-                else
-                {
-                    if (lua_pcall(L, 0, LUA_MULTRET, 0))
-                    {
-                        pd_error(o, "lua: error running `%s':\n%s", filename, lua_tostring(L, -1));
-                        lua_pop(L, 1);
-                        close(fd);
-                        pdlua_clearrequirepath(L);
-                    }
-                    else
-                    {
-                        /* succeeded */
-                        close(fd);
-                        pdlua_clearrequirepath(L);
-                    }
-                }
-            }
-            else pd_error(o, "lua: error loading `%s': canvas_open() failed", filename);
-        }
-        else error("lua: error in object:dofile() - object is null");
-    }
-    else error("lua: error in object:dofile() - object is wrong type");
-    lua_pushstring(L, buf); /* return the path as well so we can open it later with pdlua_menu_open() */
-#ifdef PDLUA_DEBUG
-    post("pdlua_dofile end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    
-    return lua_gettop(L) - n;
-}
-
-/** Initialize the pd API for Lua. */
-static void pdlua_init(lua_State *L)
-/**< Lua interpreter state. */
-{
-    lua_newtable(L);
-    lua_setglobal(L, "pd");
-    lua_getglobal(L, "pd");
-    lua_pushstring(L, "_iswindows");
-#ifdef _WIN32
-    lua_pushboolean(L, 1);
-#else
-    lua_pushboolean(L, 0);
-#endif // _WIN32
-    lua_settable(L, -3);
-    lua_pushstring(L, "_register");
-    lua_pushcfunction(L, pdlua_class_new);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_create");
-    lua_pushcfunction(L, pdlua_object_new);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_createinlets");
-    lua_pushcfunction(L, pdlua_object_createinlets);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_createoutlets");
-    lua_pushcfunction(L, pdlua_object_createoutlets);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_destroy");
-    lua_pushcfunction(L, pdlua_object_free);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_outlet");
-    lua_pushcfunction(L, pdlua_outlet);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_createreceive");
-    lua_pushcfunction(L, pdlua_receive_new);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_receivefree");
-    lua_pushcfunction(L, pdlua_receive_free);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_createclock");
-    lua_pushcfunction(L, pdlua_clock_new);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_clockfree");
-    lua_pushcfunction(L, pdlua_clock_free);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_clockset");
-    lua_pushcfunction(L, pdlua_clock_set);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_clockunset");
-    lua_pushcfunction(L, pdlua_clock_unset);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_clockdelay");
-    lua_pushcfunction(L, pdlua_clock_delay);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_dofile");
-    lua_pushcfunction(L, pdlua_dofile);
-    lua_settable(L, -3);
-    lua_pushstring(L, "send");
-    lua_pushcfunction(L, pdlua_send);
-    lua_settable(L, -3);
-    lua_pushstring(L, "getvalue");
-    lua_pushcfunction(L, pdlua_getvalue);
-    lua_settable(L, -3);
-    lua_pushstring(L, "setvalue");
-    lua_pushcfunction(L, pdlua_setvalue);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_getarray");
-    lua_pushcfunction(L, pdlua_getarray);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_readarray");
-    lua_pushcfunction(L, pdlua_readarray);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_writearray");
-    lua_pushcfunction(L, pdlua_writearray);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_redrawarray");
-    lua_pushcfunction(L, pdlua_redrawarray);
-    lua_settable(L, -3);
-    lua_pushstring(L, "post");
-    lua_pushcfunction(L, pdlua_post);
-    lua_settable(L, -3);
-    lua_pushstring(L, "_error");
-    lua_pushcfunction(L, pdlua_error);
-    lua_settable(L, -3);
-    lua_pop(L, 1);
-#ifdef PDLUA_DEBUG
-    post("pdlua_init: end. stack top is %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-}
-
-/** Pd loader hook for loading and executing Lua scripts. */
-static int pdlua_loader
-(
-    t_canvas    *canvas, /**< Pd canvas to use to find the script. */
-    char        *name /**< The name of the script (without .pd_lua extension). */
-)
-{
-    char                dirbuf[MAXPDSTRING];
-    char                *ptr;
-    int                 fd;
-    t_pdlua_readerdata  reader;
-
-#ifdef PDLUA_DEBUG
-    post("pdlua_loader: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    fd = canvas_open(canvas, name, ".pd_lua", dirbuf, &ptr, MAXPDSTRING, 1);
-    if (fd >= 0)
-    {
-        class_set_extern_dir(gensym(dirbuf));
-        pdlua_setrequirepath(L, dirbuf);
-        reader.fd = fd;
-#if LUA_VERSION_NUM	< 502
-        if (lua_load(L, pdlua_reader, &reader, name) || lua_pcall(L, 0, 0, 0))
-#else // 5.2 style
-        if (lua_load(L, pdlua_reader, &reader, name, NULL) || lua_pcall(L, 0, 0, 0))
-#endif // LUA_VERSION_NUM	< 502
-        {
-
-            error("lua: error loading `%s':\n%s", name, lua_tostring(L, -1));
-            lua_pop(L, 1);
-            close(fd);
-            pdlua_clearrequirepath(L);
-            class_set_extern_dir(&s_);
-#ifdef PDLUA_DEBUG
-            post("pdlua_loader: script error end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-            return 0;
-        }
-        close(fd);
-        pdlua_clearrequirepath(L);
-        class_set_extern_dir(&s_);
-#ifdef PDLUA_DEBUG
-        post("pdlua_loader: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-        return 1;
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_loader: no file end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    return 0;
-}
-
-/** Start the Lua runtime and register our loader hook. */
-#ifdef _WIN32
-__declspec(dllexport)
-#endif 
-void pdlua_setup(void)
-{
-    char                pd_lua_path[MAXPDSTRING];
-    t_pdlua_readerdata  reader;
-    int                 fd;
-    int                 result;
-    char*               pdluaver = "pdlua 0.7.2 (GPL) 2014 Martin Peach, based on";
-    char*               luaver = "lua 0.6~svn (GPL) 2008 Claude Heiland-Allen <claudiusmaximus@goto10.org>";
-    char                compiled[MAXPDSTRING];
-    char                luaversionStr[MAXPDSTRING];
-    const lua_Number    *luaversion = lua_version (NULL);
-    int                 lvm, lvl;
-
-    snprintf(compiled, MAXPDSTRING-1, "pdlua: compiled for pd-%d.%d on %s %s",
-             PD_MAJOR_VERSION, PD_MINOR_VERSION, __DATE__, __TIME__);
-
-    lvm = (*luaversion)/100;
-    lvl = (*luaversion) - (100*lvm);
-    snprintf(luaversionStr, MAXPDSTRING-1, "Using lua version %d.%d", lvm, lvl);
-
-#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43
-    post(pdluaver);
-    post(luaver);
-    post(compiled);
-    post(luaversionStr);
-#else
-    logpost(NULL, 3, pdluaver);
-    logpost(NULL, 3, luaver);
-    logpost(NULL, 3, compiled);
-    logpost(NULL, 3, luaversionStr);
-#endif
-    pdlua_proxyinlet_setup();
-#ifdef PDLUA_DEBUG
-    post("pdlua pdlua_proxyinlet_setup done");
-#endif // PDLUA_DEBUG
-    pdlua_proxyreceive_setup();
-#ifdef PDLUA_DEBUG
-    post("pdlua pdlua_proxyreceive_setup done");
-#endif // PDLUA_DEBUG
-    pdlua_proxyclock_setup();
-#ifdef PDLUA_DEBUG
-    post("pdlua pdlua_proxyclock_setup done");
-#endif // PDLUA_DEBUG
-#if LUA_VERSION_NUM	< 502
-    L = lua_open();
-#else // 5.2 style
-    L = luaL_newstate();
-#endif // LUA_VERSION_NUM	< 502
-#ifdef PDLUA_DEBUG
-    post("pdlua lua_open done L = %p", L);
-#endif // PDLUA_DEBUG
-    luaL_openlibs(L);
-#ifdef PDLUA_DEBUG
-    post("pdlua luaL_openlibs done");
-#endif // PDLUA_DEBUG
-    pdlua_init(L);
-#ifdef PDLUA_DEBUG
-    post("pdlua pdlua_init done");
-#endif // PDLUA_DEBUG
-    /* "pd.lua" is the Lua part of pdlua, want to keep the C part minimal */
-    /* canvas_open can't find pd.lua unless we give the path to pd beforehand like pd -path /usr/lib/extra/pdlua */
-    /* To avoid this we can use c_externdir from m_imp.h, struct _class: t_symbol *c_externdir; */
-    /* c_externdir is the directory the extern was loaded from and is also the directory contining pd.lua */
-    sprintf(pd_lua_path, "%s/pd.lua", pdlua_proxyinlet_class->c_externdir->s_name); /* the full path to pd.lua */
-#ifdef PDLUA_DEBUG
-    post("pd_lua_path %s", pd_lua_path);
-#endif // PDLUA_DEBUG
-    fd = open(pd_lua_path, O_RDONLY);
-/*    fd = canvas_open(canvas_getcurrent(), "pd", ".lua", buf, &ptr, MAXPDSTRING, 1);  looks all over and rarely succeeds */
-#ifdef PDLUA_DEBUG
-    post ("pd.lua loaded from %s", pd_lua_path);
-    post("pdlua canvas_open done fd = %d", fd);
-    post("pdlua_setup: stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-    if (fd >= 0)
-    { /* pd.lua was opened */
-        reader.fd = fd;
-#if LUA_VERSION_NUM	< 502
-        result = lua_load(L, pdlua_reader, &reader, "pd.lua");
-#else // 5.2 style
-        result = lua_load(L, pdlua_reader, &reader, "pd.lua", NULL); // mode bt for binary or text
-#endif // LUA_VERSION_NUM	< 502
-#ifdef PDLUA_DEBUG
-        post ("pdlua lua_load returned %d", result);
-#endif // PDLUA_DEBUG
-        if (0 == result)
-        {
-            result = lua_pcall(L, 0, 0, 0);
-#ifdef PDLUA_DEBUG
-            post ("pdlua lua_pcall returned %d", result);
-#endif // PDLUA_DEBUG
-        }
-        if (0 != result)
-        //if (lua_load(L, pdlua_reader, &reader, "pd.lua") || lua_pcall(L, 0, 0, 0))
-        {
-            error("lua: error loading `pd.lua':\n%s", lua_tostring(L, -1));
-            error("lua: loader will not be registered!");
-            error("lua: (is `pd.lua' in Pd's path list?)");
-            lua_pop(L, 1);
-            close(fd);
-        }
-        else
-        {
-            close(fd);
-            sys_register_loader(pdlua_loader);
-        }
-    }
-    else
-    {
-        error("lua: error loading `pd.lua': canvas_open() failed");
-        error("lua: loader will not be registered!");
-    }
-#ifdef PDLUA_DEBUG
-    post("pdlua_setup: end. stack top %d", lua_gettop(L));
-#endif // PDLUA_DEBUG
-
-}
-
-/* EOF */
+/* This is a version hacked by Martin Peach 20110120 martin.peach@sympatico.ca */
+/* Reformmatted the code and added some debug messages. Changed the name of the class to pdlua */
+/** @file lua.c 
+ *  @brief pdlua -- a Lua embedding for Pd.
+ *  @author Claude Heiland-Allen <claude@mathr.co.uk>
+ *  @date 2008
+ *  @version 0.6~svn
+ *
+ * Copyright (C) 2007,2008 Claude Heiland-Allen <claude@mathr.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */ 
+
+/* various C stuff, mainly for reading files */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h> // for open
+#include <sys/stat.h> // for open
+#ifdef _MSC_VER
+#include <io.h>
+#include <fcntl.h> // for open
+#define read _read
+#define close _close
+#define ssize_t int
+#define snprintf _snprintf
+#else
+#include <sys/fcntl.h> // for open
+#include <unistd.h>
+#endif
+/* we use Lua */
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+/* we use Pd */
+#include "m_pd.h"
+#include "s_stuff.h" // for sys_register_loader()
+#include "m_imp.h" // for struct _class
+/* BAD: support for Pd < 0.41 */
+
+#if PD_MAJOR_VERSION == 0
+# if PD_MINOR_VERSION >= 41
+#  define PDLUA_PD41
+/* use new garray support that is 64-bit safe */
+#  define PDLUA_ARRAYGRAB garray_getfloatwords
+#  define PDLUA_ARRAYTYPE t_word
+#  define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)].w_float)
+# elif PD_MINOR_VERSION >= 40
+#  define PDLUA_PD40
+/* use old garray support, not 64-bit safe */
+#  define PDLUA_ARRAYGRAB garray_getfloatarray
+#  define PDLUA_ARRAYTYPE t_float
+#  define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)])
+# elif PD_MINOR_VERSION >= 39
+#  define PDLUA_PD39
+/* use old garray support, not 64-bit safe */
+#  define PDLUA_ARRAYGRAB garray_getfloatarray
+#  define PDLUA_ARRAYTYPE t_float
+#  define PDLUA_ARRAYELEM(arr,idx) ((arr)[(idx)])
+# else
+#  error "Pd version is too old, please upgrade"
+# endif
+#else
+# error "Pd version is too new, please file a bug report"
+#endif
+
+/* BAD: end of bad section */
+
+/* If defined, PDLUA_DEBUG lets pdlua post a lot of text */
+//#define PDLUA_DEBUG post
+#ifndef PDLUA_DEBUG
+//static void PDLUA_DEBUG(const char *fmt, ...) {;}
+# define PDLUA_DEBUG(x,y)
+# define PDLUA_DEBUG2(x,y0,y1)
+# define PDLUA_DEBUG3(x,y0,y1,y2)
+#else
+# define PDLUA_DEBUG2 PDLUA_DEBUG
+# define PDLUA_DEBUG3 PDLUA_DEBUG
+#endif
+
+/** Global Lua interpreter state, needed in the constructor. */
+static lua_State *L;
+
+/** State for the Lua file reader. */
+typedef struct pdlua_readerdata
+{
+    int         fd; /**< File descriptor to read from. */
+    char        buffer[MAXPDSTRING]; /**< Buffer to read into. */
+} t_pdlua_readerdata;
+
+/** Pd object data. */
+typedef struct pdlua 
+{
+    t_object                pd; /**< We are a Pd object. */
+    int                     inlets; /**< Number of inlets. */
+    struct pdlua_proxyinlet *in; /**< The inlets themselves. */
+    int                     outlets; /**< Number of outlets. */
+    t_outlet                **out; /**< The outlets themselves. */
+    t_canvas                *canvas; /**< The canvas that the object was created on. */
+} t_pdlua;
+
+/** Proxy inlet object data. */
+typedef struct pdlua_proxyinlet
+{
+    t_pd            pd; /**< Minimal Pd object. */
+    struct pdlua    *owner; /**< The owning object to forward inlet messages to. */
+    unsigned int    id; /**< The number of this inlet. */
+} t_pdlua_proxyinlet;
+
+/** Proxy receive object data. */
+typedef struct pdlua_proxyreceive
+{
+    t_pd            pd; /**< Minimal Pd object. */
+    struct pdlua    *owner; /**< The owning object to forward received messages to. */
+    t_symbol        *name; /**< The receive-symbol to bind to. */
+} t_pdlua_proxyreceive;
+
+/** Proxy clock object data. */
+typedef struct pdlua_proxyclock
+{
+    t_pd            pd; /**< Minimal Pd object. */
+    struct pdlua    *owner; /**< Object to forward messages to. */
+    t_clock         *clock; /** Pd clock to use. */
+} t_pdlua_proxyclock;
+/* prototypes*/
+
+static const char *pdlua_reader (lua_State *L, void *rr, size_t *size);
+/** Proxy inlet 'anything' method. */
+static void pdlua_proxyinlet_anything (t_pdlua_proxyinlet *p, t_symbol *s, int argc, t_atom *argv);
+/** Proxy inlet initialization. */
+static void pdlua_proxyinlet_init (t_pdlua_proxyinlet *p, struct pdlua *owner, unsigned int id);
+/** Register the proxy inlet class with Pd. */
+static void pdlua_proxyinlet_setup (void);
+/** Proxy receive 'anything' method. */
+static void pdlua_proxyreceive_anything (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv);
+/** Proxy receive allocation and initialization. */
+static t_pdlua_proxyreceive *pdlua_proxyreceive_new (struct pdlua *owner, t_symbol *name);
+/** Proxy receive cleanup and deallocation. */
+static void pdlua_proxyreceive_free (t_pdlua_proxyreceive *r /**< The proxy receive to free. */);
+/** Register the proxy receive class with Pd. */
+static void pdlua_proxyreceive_setup (void);
+/** Proxy clock 'bang' method. */
+static void pdlua_proxyclock_bang (t_pdlua_proxyclock *c);
+/** Proxy clock allocation and initialization. */
+static t_pdlua_proxyclock *pdlua_proxyclock_new (struct pdlua *owner);
+/** Register the proxy clock class with Pd. */
+static void pdlua_proxyclock_setup (void);
+/** Dump an array of atoms into a Lua table. */
+static void pdlua_pushatomtable (int argc, t_atom *argv);
+/** Pd object constructor. */
+static t_pdlua *pdlua_new (t_symbol *s, int argc, t_atom *argv);
+/** Pd object destructor. */
+static void pdlua_free (t_pdlua *o );
+static void pdlua_stack_dump (lua_State *L);
+/** a handler for the open item in the right-click menu (mrpeach 20111025) */
+/** Here we find the lua code for the object and open it in an editor */
+static void pdlua_menu_open (t_pdlua *o);
+/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */
+static int pdlua_class_new (lua_State *L);
+/** Lua object creation. */
+static int pdlua_object_new (lua_State *L);
+/** Lua object inlet creation. */
+static int pdlua_object_createinlets (lua_State *L);
+/** Lua object outlet creation. */
+static int pdlua_object_createoutlets (lua_State *L);
+/** Lua object receive creation. */
+static int pdlua_receive_new (lua_State *L);
+/** Lua object receive destruction. */
+static int pdlua_receive_free (lua_State *L);
+/** Lua object clock creation. */
+static int pdlua_clock_new (lua_State *L);
+/** Lua proxy clock delay. */
+static int pdlua_clock_delay (lua_State *L);
+/** Lua proxy clock set. */
+static int pdlua_clock_set (lua_State *L);
+/** Lua proxy clock unset. */
+static int pdlua_clock_unset (lua_State *L);
+/** Lua proxy clock destruction. */
+static int pdlua_clock_free (lua_State *L);
+/** Lua object destruction. */
+static int pdlua_object_free (lua_State *L);
+/** Dispatch Pd inlet messages to Lua objects. */
+static void pdlua_dispatch (t_pdlua *o, unsigned int inlet, t_symbol *s, int argc, t_atom *argv);
+/** Dispatch Pd receive messages to Lua objects. */
+static void pdlua_receivedispatch (t_pdlua_proxyreceive *r, t_symbol *s, int argc, t_atom *argv);
+/** Dispatch Pd clock messages to Lua objects. */
+static void pdlua_clockdispatch(t_pdlua_proxyclock *clock);
+/** Convert a Lua table into a Pd atom array. */
+static t_atom *pdlua_popatomtable (lua_State *L, int *count, t_pdlua *o);
+/** Send a message from a Lua object outlet. */
+static int pdlua_outlet (lua_State *L);
+/** Send a message from a Lua object to a Pd receiver. */
+static int pdlua_send (lua_State *L);
+/** Set a [value] object's value. */
+static int pdlua_setvalue (lua_State *L);
+/** Get a [value] object's value. */
+static int pdlua_getvalue (lua_State *L);
+/** Get a [table] object's array. */
+static int pdlua_getarray (lua_State *L);
+/** Read from a [table] object's array. */
+static int pdlua_readarray (lua_State *L);
+/** Write to a [table] object's array. */
+static int pdlua_writearray (lua_State *L);
+/** Redraw a [table] object's graph. */
+static int pdlua_redrawarray (lua_State *L);
+/** Post to Pd's console. */
+static int pdlua_post (lua_State *L);
+/** Report an error from a Lua object to Pd's console. */
+static int pdlua_error (lua_State *L);
+static void pdlua_setrequirepath (lua_State *L, const char *path);
+static void pdlua_clearrequirepath (lua_State *L);
+/** Run a Lua script using Pd's path. */
+static int pdlua_dofile (lua_State *L);
+/** Initialize the pd API for Lua. */
+static void pdlua_init (lua_State *L);
+/** Pd loader hook for loading and executing Lua scripts. */
+static int pdlua_loader_legacy (t_canvas *canvas, char *name);
+/** Start the Lua runtime and register our loader hook. */
+#ifdef _WIN32
+__declspec(dllexport)
+#endif 
+void pdlua_setup (void);
+/* end prototypes*/
+
+/* globals */
+struct pdlua_proxyinlet;
+struct pdlua_proxyreceive;
+struct pdlua_proxyclock;
+/** Proxy inlet class pointer. */
+static t_class *pdlua_proxyinlet_class;
+/** Proxy receive class pointer. */
+static t_class *pdlua_proxyreceive_class;
+/** Proxy clock class pointer. */
+static t_class *pdlua_proxyclock_class;
+
+/** Lua file reader callback. */
+static const char *pdlua_reader
+(
+    lua_State *L, /**< Lua interpreter state. */
+    void *rr, /**< Lua file reader state. */
+    size_t *size /**< How much data we have read. */
+)
+{
+    t_pdlua_readerdata  *r = rr;
+    ssize_t             s;
+    PDLUA_DEBUG("pdlua_reader: fd is %d", r->fd);
+    s = read(r->fd, r->buffer, MAXPDSTRING-2);
+    PDLUA_DEBUG("pdlua_reader: s is %ld", s);////////
+    if (s <= 0)
+    {
+        *size = 0;
+        return NULL;
+    }
+    else
+    {
+        *size = s;
+        return r->buffer;
+    }
+}
+
+/** Proxy inlet 'anything' method. */
+static void pdlua_proxyinlet_anything
+(
+    t_pdlua_proxyinlet  *p, /**< The proxy inlet that received the message. */
+    t_symbol            *s, /**< The message selector. */
+    int                 argc, /**< The message length. */
+    t_atom              *argv /**< The atoms in the message. */
+)
+{
+    pdlua_dispatch(p->owner, p->id, s, argc, argv);
+}
+
+/** Proxy inlet initialization. */
+static void pdlua_proxyinlet_init
+(
+    t_pdlua_proxyinlet  *p, /**< The proxy inlet to initialize. */
+    struct pdlua        *owner, /**< The owning object. */
+    unsigned int        id /**< The inlet number. */
+)
+{
+    p->pd = pdlua_proxyinlet_class;
+    p->owner = owner;
+    p->id = id;
+}
+
+/** Register the proxy inlet class with Pd. */
+static void pdlua_proxyinlet_setup(void)
+{
+    pdlua_proxyinlet_class = class_new(gensym("pdlua proxy inlet"), 0, 0, sizeof(t_pdlua_proxyinlet), 0, 0);
+    class_addanything(pdlua_proxyinlet_class, pdlua_proxyinlet_anything);
+}
+
+/** Proxy receive 'anything' method. */
+static void pdlua_proxyreceive_anything(
+    t_pdlua_proxyreceive    *r, /**< The proxy receive that received the message. */
+    t_symbol                *s, /**< The message selector. */
+    int                     argc, /**< The message length. */
+    t_atom                  *argv /**< The atoms in the message. */
+)
+{
+    pdlua_receivedispatch(r, s, argc, argv);
+}
+
+/** Proxy receive allocation and initialization. */
+static t_pdlua_proxyreceive *pdlua_proxyreceive_new
+(
+    struct pdlua    *owner, /**< The owning object. */
+    t_symbol        *name /**< The symbol to bind to. */
+)
+{
+    t_pdlua_proxyreceive *r = malloc(sizeof(t_pdlua_proxyreceive));
+    r->pd = pdlua_proxyreceive_class;
+    r->owner = owner;
+    r->name = name;
+    pd_bind(&r->pd, r->name);
+    return r;
+}
+
+/** Proxy receive cleanup and deallocation. */
+static void pdlua_proxyreceive_free(t_pdlua_proxyreceive *r /**< The proxy receive to free. */)
+{
+    pd_unbind(&r->pd, r->name);
+    r->pd = NULL;
+    r->owner = NULL;
+    r->name = NULL;
+    free(r);
+}
+
+/** Register the proxy receive class with Pd. */
+static void pdlua_proxyreceive_setup()
+{
+    pdlua_proxyreceive_class = class_new(gensym("pdlua proxy receive"), 0, 0, sizeof(t_pdlua_proxyreceive), 0, 0);
+    class_addanything(pdlua_proxyreceive_class, pdlua_proxyreceive_anything);
+}
+
+/** Proxy clock 'bang' method. */
+static void pdlua_proxyclock_bang(t_pdlua_proxyclock *c /**< The proxy clock that received the message. */)
+{
+    pdlua_clockdispatch(c);
+}
+
+/** Proxy clock allocation and initialization. */
+static t_pdlua_proxyclock *pdlua_proxyclock_new
+(
+    struct pdlua *owner /**< The object to forward messages to. */
+)
+{
+    t_pdlua_proxyclock *c = malloc(sizeof(t_pdlua_proxyclock));
+    c->pd = pdlua_proxyclock_class;
+    c->owner = owner;
+    c->clock = clock_new(c, (t_method) pdlua_proxyclock_bang);
+    return c;
+}
+
+/** Register the proxy clock class with Pd. */
+static void pdlua_proxyclock_setup(void)
+{
+    pdlua_proxyclock_class = class_new(gensym("pdlua proxy clock"), 0, 0, sizeof(t_pdlua_proxyclock), 0, 0);
+}
+
+/** Dump an array of atoms into a Lua table. */
+static void pdlua_pushatomtable
+(
+    int     argc, /**< The number of atoms in the array. */
+    t_atom  *argv /**< The array of atoms. */
+)
+{
+    int i;
+
+    PDLUA_DEBUG("pdlua_pushatomtable: stack top %d", lua_gettop(L));
+    lua_newtable(L);
+    for (i = 0; i < argc; ++i)
+    {
+        lua_pushnumber(L, i+1);
+        switch (argv[i].a_type)
+        {
+            case A_FLOAT:
+                lua_pushnumber(L, argv[i].a_w.w_float);
+                break;
+            case A_SYMBOL:
+                lua_pushstring(L, argv[i].a_w.w_symbol->s_name);
+                break;
+            case A_POINTER: /* FIXME: check experimentality */
+                lua_pushlightuserdata(L, argv[i].a_w.w_gpointer);
+            break;
+            default:
+                error("lua: zomg weasels!");
+                lua_pushnil(L);
+            break;
+        }
+        lua_settable(L, -3);
+    }
+    PDLUA_DEBUG("pdlua_pushatomtable: end. stack top %d", lua_gettop(L));
+}
+
+/** Pd object constructor. */
+static t_pdlua *pdlua_new
+(
+    t_symbol    *s, /**< The construction message selector. */
+    int         argc, /**< The construction message atom count. */
+    t_atom      *argv /**< The construction message atoms. */
+)
+{
+    int i;
+    PDLUA_DEBUG("pdlua_new: s->s_name is %s", s->s_name);
+    for (i = 0; i < argc; ++i)
+    {
+        switch (argv[i].a_type)
+        {
+        case A_FLOAT:
+            PDLUA_DEBUG2("argv[%d]: %f", i, argv[i].a_w.w_float);
+            break;
+        case A_SYMBOL:
+            PDLUA_DEBUG2("argv[%d]: %s", i, argv[i].a_w.w_symbol->s_name);
+            break;
+        default:
+            error("pdlua_new: bad argument type"); // should never happen
+            return NULL;
+        }
+    }
+    PDLUA_DEBUG("pdlua_new: start with stack top %d", lua_gettop(L));
+    lua_getglobal(L, "pd");
+    lua_getfield(L, -1, "_constructor");
+    lua_pushstring(L, s->s_name);
+    pdlua_pushatomtable(argc, argv);
+    PDLUA_DEBUG("pdlua_new: before lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L));
+    if (lua_pcall(L, 2, 1, 0))
+    {
+        error("pdlua_new: error in constructor for `%s':\n%s", s->s_name, lua_tostring(L, -1));
+        lua_pop(L, 2); /* pop the error string and the global "pd" */
+        return NULL;
+    }
+    else
+    {
+        t_pdlua *object = NULL;
+        PDLUA_DEBUG("pdlua_new: done lua_pcall(L, 2, 1, 0) stack top %d", lua_gettop(L));
+        if (lua_islightuserdata(L, -1))
+        {
+            object = lua_touserdata(L, -1);
+            lua_pop(L, 2);/* pop the userdata and the global "pd" */
+            PDLUA_DEBUG2("pdlua_new: before returning object %p stack top %d", object, lua_gettop(L));
+             return object;
+        }
+        else
+        {
+            lua_pop(L, 2);/* pop the userdata and the global "pd" */
+            PDLUA_DEBUG("pdlua_new: done FALSE lua_islightuserdata(L, -1)", 0);
+            return NULL;
+        }
+    }
+}
+
+/** Pd object destructor. */
+static void pdlua_free( t_pdlua *o /**< The object to destruct. */)
+{
+    PDLUA_DEBUG("pdlua_free: stack top %d", lua_gettop(L));
+    lua_getglobal(L, "pd");
+    lua_getfield (L, -1, "_destructor");
+    lua_pushlightuserdata(L, o);
+    if (lua_pcall(L, 1, 0, 0))
+    {
+        error("lua: error in destructor:\n%s", lua_tostring(L, -1));
+        lua_pop(L, 1); /* pop the error string */
+    }
+    lua_pop(L, 1); /* pop the global "pd" */
+    PDLUA_DEBUG("pdlua_free: end. stack top %d", lua_gettop(L));
+    return;
+}
+
+static void pdlua_stack_dump (lua_State *L)
+{
+    int i;
+    int top = lua_gettop(L);
+
+    for (i = 1; i <= top; i++)
+    {  /* repeat for each level */
+        int t = lua_type(L, i);
+        switch (t)
+        {
+            case LUA_TSTRING:  /* strings */
+                printf("`%s'", lua_tostring(L, i));
+                break;
+    
+            case LUA_TBOOLEAN:  /* booleans */
+                printf(lua_toboolean(L, i) ? "true" : "false");
+                break;
+    
+            case LUA_TNUMBER:  /* numbers */
+                printf("%g", lua_tonumber(L, i));
+                break;
+    
+            default:  /* other values */
+                printf("%s", lua_typename(L, t));
+                break;
+        }
+        printf("  ");  /* put a separator */
+    }
+    printf("\n");  /* end the listing */
+}
+
+/** a handler for the open item in the right-click menu (mrpeach 20111025) */
+/** Here we find the lua code for the object and open it in an editor */
+static void pdlua_menu_open(t_pdlua *o)
+{
+    const char  *name;
+    const char  *path;
+    char        pathname[FILENAME_MAX];
+    t_class     *class;
+
+    PDLUA_DEBUG("pdlua_menu_open stack top is %d", lua_gettop(L));
+    /** Get the scriptname of the object */
+    lua_getglobal(L, "pd");
+    lua_getfield(L, -1, "_whoami");
+    lua_pushlightuserdata(L, o);
+    if (lua_pcall(L, 1, 1, 0))
+    {
+        error("lua: error in whoami:\n%s", lua_tostring(L, -1));
+        lua_pop(L, 2); /* pop the error string and the global "pd" */
+        return;
+    }
+    name = luaL_checkstring(L, -1);
+    PDLUA_DEBUG3("pdlua_menu_open: L is %p, name is %s stack top is %d", L, name, lua_gettop(L));
+    if (name)
+    {
+        if (name[strlen(name)-1] == 'x')
+        {
+            /* pdluax is a class, the particular file should loadable by name alone, we hope */
+            sprintf(pathname, "%s", name);
+            lua_pop(L, 2); /* pop name and the global "pd" */
+        }
+        else
+        {
+            lua_getglobal(L, "pd");
+            lua_getfield(L, -1, "_get_class");
+            lua_pushlightuserdata(L, o);
+            if (lua_pcall(L, 1, 1, 0))
+            {
+                error("lua: error in get_class:\n%s", lua_tostring(L, -1));
+                lua_pop(L, 4); /* pop the error string, global "pd", name, global "pd"*/
+                return;
+            }
+            class = (t_class *)lua_touserdata(L, -1);
+            path = class->c_externdir->s_name;
+            sprintf(pathname, "%s/%s", path, name);
+            lua_pop(L, 4); /* pop class, global "pd", name, global "pd"*/
+        }
+#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43
+        post("Opening %s for editing", pathname);
+#else
+        logpost(NULL, 3, "Opening %s for editing", pathname);
+#endif
+        sys_vgui("::pd_menucommands::menu_openfile {%s}\n", pathname);
+    }
+    PDLUA_DEBUG("pdlua_menu_open end. stack top is %d", lua_gettop(L));
+}
+
+/** Lua class registration. This is equivalent to the "setup" method for an ordinary Pd class */
+static int pdlua_class_new(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Class name string.
+  * \par Outputs:
+  * \li \c 1 Pd class pointer.
+  * */
+{
+    const char  *name;
+    t_class     *c;
+
+    name = luaL_checkstring(L, 1);
+    PDLUA_DEBUG3("pdlua_class_new: L is %p, name is %s stack top is %d", L, name, lua_gettop(L));
+    c = class_new(gensym((char *) name), (t_newmethod) pdlua_new,
+        (t_method) pdlua_free, sizeof(t_pdlua), CLASS_NOINLET, A_GIMME, 0);
+
+/* a class with a "menu-open" method will have the "Open" item highlighted in the right-click menu */
+    class_addmethod(c, (t_method)pdlua_menu_open, gensym("menu-open"), A_NULL);/* (mrpeach 20111025) */
+/**/
+
+    lua_pushlightuserdata(L, c);
+    PDLUA_DEBUG("pdlua_class_new: end stack top is %d", lua_gettop(L));
+    return 1;
+}
+
+/** Lua object creation. */
+static int pdlua_object_new(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd class pointer.
+  * \par Outputs:
+  * \li \c 2 Pd object pointer.
+  * */
+{
+    PDLUA_DEBUG("pdlua_object_new: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_class *c = lua_touserdata(L, 1);
+        if (c)
+        {
+            PDLUA_DEBUG("pdlua_object_new: path is %s", c->c_externdir->s_name);
+            t_pdlua *o = (t_pdlua *) pd_new(c);
+            if (o)
+            {
+                o->inlets = 0;
+                o->in = NULL;
+                o->outlets = 0;
+                o->out = NULL;
+                o->canvas = canvas_getcurrent();
+                lua_pushlightuserdata(L, o);
+                PDLUA_DEBUG("pdlua_object_new: success end. stack top is %d", lua_gettop(L));
+                return 1;
+            }
+        }
+    }
+    PDLUA_DEBUG("pdlua_object_new: fail end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua object inlet creation. */
+static int pdlua_object_createinlets(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * \li \c 2 Number of inlets.
+  * */
+{
+    int i;
+
+    PDLUA_DEBUG("pdlua_object_createinlets: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua *o = lua_touserdata(L, 1);
+        if (o)
+        {
+            o->inlets = luaL_checknumber(L, 2);
+            o->in = malloc(o->inlets * sizeof(t_pdlua_proxyinlet));
+            for (i = 0; i < o->inlets; ++i)
+            {
+                pdlua_proxyinlet_init(&o->in[i], o, i);
+                inlet_new(&o->pd, &o->in[i].pd, 0, 0);
+            }
+        }
+    }
+    PDLUA_DEBUG("pdlua_object_createinlets: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua object outlet creation. */
+static int pdlua_object_createoutlets(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * \li \c 2 Number of outlets.
+  * */
+{
+    int i;
+
+    PDLUA_DEBUG("pdlua_object_createoutlets: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua *o = lua_touserdata(L, 1);
+        if (o)
+        {
+            o->outlets = luaL_checknumber(L, 2);
+            if (o->outlets > 0)
+            {
+                o->out = malloc(o->outlets * sizeof(t_outlet *));
+                for (i = 0; i < o->outlets; ++i) o->out[i] = outlet_new(&o->pd, 0);
+            }
+            else o->out = NULL;
+        }
+    }
+    PDLUA_DEBUG("pdlua_object_createoutlets: end stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua object receive creation. */
+static int pdlua_receive_new(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * \li \c 2 Receive name string.
+  * \par Outputs:
+  * \li \c 1 Pd receive pointer.
+  * */
+{
+    PDLUA_DEBUG("pdlua_receive_new: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua *o = lua_touserdata(L, 1);
+        if (o)
+        {
+            const char *name = luaL_checkstring(L, 2);
+            if (name)
+            {
+                t_pdlua_proxyreceive *r =  pdlua_proxyreceive_new(o, gensym((char *) name)); /* const cast */
+                lua_pushlightuserdata(L, r);
+                PDLUA_DEBUG("pdlua_receive_new: success end. stack top is %d", lua_gettop(L));
+                return 1;
+            }
+        }
+    }
+    PDLUA_DEBUG("pdlua_receive_new: fail end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua object receive destruction. */
+static int pdlua_receive_free(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd recieve pointer.
+  * */
+{
+    PDLUA_DEBUG("pdlua_receive_free: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua_proxyreceive *r = lua_touserdata(L, 1);
+        if (r) pdlua_proxyreceive_free(r);
+    }
+    PDLUA_DEBUG("pdlua_receive_free: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua object clock creation. */
+static int pdlua_clock_new(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * \par Outputs:
+  * \li \c 1 Pd clock pointer.
+  * */
+{
+    PDLUA_DEBUG("pdlua_clock_new: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua *o = lua_touserdata(L, 1);
+        if (o)
+        {
+            t_pdlua_proxyclock *c =  pdlua_proxyclock_new(o);
+            lua_pushlightuserdata(L, c);
+            PDLUA_DEBUG("pdlua_clock_new: success end. stack top is %d", lua_gettop(L));
+            return 1;
+        }
+    }
+    PDLUA_DEBUG("pdlua_clock_new: fail end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua proxy clock delay. */
+static int pdlua_clock_delay(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd clock pointer.
+  * \li \c 2 Number of milliseconds to delay.
+  * */
+{
+    PDLUA_DEBUG("pdlua_clock_delay: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
+        if (c)
+        {
+            double delaytime = luaL_checknumber(L, 2);
+            clock_delay(c->clock, delaytime);
+        }
+    }
+    PDLUA_DEBUG("pdlua_clock_delay: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua proxy clock set. */
+static int pdlua_clock_set(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd clock pointer.
+  * \li \c 2 Number to set the clock.
+  * */
+{
+    PDLUA_DEBUG("pdlua_clock_set: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
+        if (c)
+        {
+            double systime = luaL_checknumber(L, 2);
+            clock_set(c->clock, systime);
+        }
+    }
+    PDLUA_DEBUG("pdlua_clock_set: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua proxy clock unset. */
+static int pdlua_clock_unset(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd clock pointer.
+  * */
+{
+    PDLUA_DEBUG("pdlua_clock_unset: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
+        if (c) clock_unset(c->clock);
+    }
+    PDLUA_DEBUG("pdlua_clock_unset: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua proxy clock destruction. */
+static int pdlua_clock_free(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd clock pointer.
+  * */
+{
+    PDLUA_DEBUG("pdlua_clock_free: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua_proxyclock *c = lua_touserdata(L, 1);
+        if (c)
+        {
+            clock_free(c->clock);
+            free(c);
+        }
+    }
+    PDLUA_DEBUG("pdlua_clock_free: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Lua object destruction. */
+static int pdlua_object_free(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * */
+{
+    int i;
+
+    PDLUA_DEBUG("pdlua_object_free: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        t_pdlua *o = lua_touserdata(L, 1);
+        if (o)
+        {
+            if (o->in) free(o->in);
+            if(o->out)
+            {
+                for (i = 0; i < o->outlets; ++i) outlet_free(o->out[i]);
+                free(o->out);
+                o->out = NULL;
+            }
+        }
+    }
+    PDLUA_DEBUG("pdlua_object_free: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Dispatch Pd inlet messages to Lua objects. */
+static void pdlua_dispatch
+(
+    t_pdlua         *o, /**< The object that received the message. */
+    unsigned int    inlet, /**< The inlet that the message arrived at. */
+    t_symbol        *s, /**< The message selector. */
+    int             argc, /**< The message length. */
+    t_atom          *argv /**< The atoms in the message. */
+)
+{
+    PDLUA_DEBUG("pdlua_dispatch: stack top %d", lua_gettop(L));
+    lua_getglobal(L, "pd");
+    lua_getfield (L, -1, "_dispatcher");
+    lua_pushlightuserdata(L, o);
+    lua_pushnumber(L, inlet + 1); /* C has 0.., Lua has 1.. */
+    lua_pushstring(L, s->s_name);
+    pdlua_pushatomtable(argc, argv);
+    if (lua_pcall(L, 4, 0, 0))
+    {
+        pd_error(o, "lua: error in dispatcher:\n%s", lua_tostring(L, -1));
+        lua_pop(L, 1); /* pop the error string */
+    }
+    lua_pop(L, 1); /* pop the global "pd" */
+    PDLUA_DEBUG("pdlua_dispatch: end. stack top %d", lua_gettop(L));
+    return;  
+}
+
+/** Dispatch Pd receive messages to Lua objects. */
+static void pdlua_receivedispatch
+(
+    t_pdlua_proxyreceive    *r, /**< The proxy receive that received the message. */
+    t_symbol                *s, /**< The message selector. */
+    int                     argc, /**< The message length. */
+    t_atom                  *argv /**< The atoms in the message. */
+)
+{
+    PDLUA_DEBUG("pdlua_receivedispatch: stack top %d", lua_gettop(L));
+    lua_getglobal(L, "pd");
+    lua_getfield (L, -1, "_receivedispatch");
+    lua_pushlightuserdata(L, r);
+    lua_pushstring(L, s->s_name);
+    pdlua_pushatomtable(argc, argv);
+    if (lua_pcall(L, 3, 0, 0))
+    {
+        pd_error(r->owner, "lua: error in receive dispatcher:\n%s", lua_tostring(L, -1));
+        lua_pop(L, 1); /* pop the error string */
+    }
+    lua_pop(L, 1); /* pop the global "pd" */
+    PDLUA_DEBUG("pdlua_receivedispatch: end. stack top %d", lua_gettop(L));
+    return;  
+}
+
+/** Dispatch Pd clock messages to Lua objects. */
+static void pdlua_clockdispatch( t_pdlua_proxyclock *clock)
+/**< The proxy clock that received the message. */
+{
+    PDLUA_DEBUG("pdlua_clockdispatch: stack top %d", lua_gettop(L));
+    lua_getglobal(L, "pd");
+    lua_getfield (L, -1, "_clockdispatch");
+    lua_pushlightuserdata(L, clock);
+    if (lua_pcall(L, 1, 0, 0))
+    {
+        pd_error(clock->owner, "lua: error in clock dispatcher:\n%s", lua_tostring(L, -1));
+        lua_pop(L, 1); /* pop the error string */
+    }
+    lua_pop(L, 1); /* pop the global "pd" */
+    PDLUA_DEBUG("pdlua_clockdispatch: end. stack top %d", lua_gettop(L));
+    return;  
+}
+
+/** Convert a Lua table into a Pd atom array. */
+static t_atom *pdlua_popatomtable
+(
+    lua_State   *L, /**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c -1 Table to convert.
+  * */
+    int         *count, /**< Where to store the array length. */
+    t_pdlua     *o /**< Object reference for error messages. */
+)
+{
+    int         i;
+    int         ok = 1;
+    t_float     f;
+    const char  *s;
+    void        *p;
+    size_t      sl;
+    t_atom      *atoms = NULL;
+
+    PDLUA_DEBUG("pdlua_popatomtable: stack top %d", lua_gettop(L));
+    if (lua_istable(L, -1))
+    {
+#if LUA_VERSION_NUM	< 502
+        *count = lua_objlen(L, -1);
+#else // 5.2 style
+        *count = lua_rawlen(L, -1);
+#endif // LUA_VERSION_NUM	< 502
+        if (*count > 0) atoms = malloc(*count * sizeof(t_atom));
+        i = 0;
+        lua_pushnil(L);
+        while (lua_next(L, -2) != 0)
+        {
+            if (i == *count)
+            {
+                pd_error(o, "lua: error: too many table elements");
+                ok = 0;
+                break;
+            }
+            switch (lua_type(L, -1))
+            {
+                case (LUA_TNUMBER):
+                    f = lua_tonumber(L, -1);
+                    SETFLOAT(&atoms[i], f);
+                    break;
+                case (LUA_TSTRING):
+                    s = lua_tolstring(L, -1, &sl);
+                    if (s)
+                    {
+                        if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)");
+                        SETSYMBOL(&atoms[i], gensym((char *) s));
+                    }
+                    else
+                    {
+                        pd_error(o, "lua: error: null string in table");
+                        ok = 0;
+                    }
+                    break;
+                case (LUA_TLIGHTUSERDATA): /* FIXME: check experimentality */
+                    p = lua_touserdata(L, -1);
+                    SETPOINTER(&atoms[i], p);
+                    break;
+                default:
+                    pd_error(o, "lua: error: table element must be number or string or pointer");
+                    ok = 0;
+                    break;
+            }
+            lua_pop(L, 1);
+            ++i;
+        }
+        if (i != *count)
+        {
+            pd_error(o, "lua: error: too few table elements");
+            ok = 0;
+        }
+    }
+    else 
+    {
+        pd_error(o, "lua: error: not a table");
+        ok = 0;
+    }
+    lua_pop(L, 1);
+    PDLUA_DEBUG("pdlua_popatomtable: end. stack top %d", lua_gettop(L));
+    if (ok) return atoms;
+    if (atoms) free(atoms);
+    return NULL;
+}
+
+/** Send a message from a Lua object outlet. */
+static int pdlua_outlet(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * \li \c 2 Outlet number.
+  * \li \c 3 Message selector string.
+  * \li \c 4 Message atom table.
+  * */
+{
+    t_pdlua         *o;
+    int             out;
+    size_t          sl;
+    const char      *s;
+    t_symbol        *sym;
+    int             count;
+    t_atom          *atoms;
+
+    PDLUA_DEBUG("pdlua_outlet: stack top %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        o = lua_touserdata(L, 1);
+        if (o) 
+        {
+            if (lua_isnumber(L, 2)) out = lua_tonumber(L, 2) - 1; /* C has 0.., Lua has 1.. */
+            else
+            {
+                pd_error(o, "lua: error: outlet must be a number");
+                lua_pop(L, 4); /* pop all the arguments */
+                return 0;
+            }
+            if (0 <= out && out < o->outlets) 
+            {
+                if (lua_isstring(L, 3)) 
+                {
+                    s = lua_tolstring(L, 3, &sl);
+                    sym = gensym((char *) s); /* const cast */
+                    if (s)
+                    {
+                        if (strlen(s) != sl) pd_error(o, "lua: warning: symbol munged (contains \\0 in body)");
+                        lua_pushvalue(L, 4);
+                        atoms = pdlua_popatomtable(L, &count, o);
+                        if (count == 0 || atoms) outlet_anything(o->out[out], sym, count, atoms);
+                        else pd_error(o, "lua: error: no atoms??");
+                        if (atoms) 
+                        {
+                            free(atoms);
+                            lua_pop(L, 4); /* pop all the arguments */
+                            return 0;
+                        }
+                    }
+                    else pd_error(o, "lua: error: null selector");
+                }
+                else pd_error(o, "lua: error: selector must be a string");
+            }
+            else pd_error(o, "lua: error: outlet out of range");
+        }
+        else error("lua: error: no object to outlet from");
+    }
+    else error("lua: error: bad arguments to outlet");
+    lua_pop(L, 4); /* pop all the arguments */
+    PDLUA_DEBUG("pdlua_outlet: end. stack top %d", lua_gettop(L));
+    return 0;
+}
+
+/** Send a message from a Lua object to a Pd receiver. */
+static int pdlua_send(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Receiver string.
+  * \li \c 2 Message selector string.
+  * \li \c 3 Message atom table.
+  * */
+
+{
+    size_t          receivenamel;
+    const char      *receivename;
+    t_symbol        *receivesym;
+    size_t          selnamel;
+    const char      *selname;
+    t_symbol        *selsym;
+    int             count;
+    t_atom          *atoms;
+
+    PDLUA_DEBUG("pdlua_send: stack top is %d", lua_gettop(L));
+    if (lua_isstring(L, 1)) 
+    {
+        receivename = lua_tolstring(L, 1, &receivenamel);
+        receivesym = gensym((char *) receivename); /* const cast */
+        if (receivesym) 
+        {
+            if (strlen(receivename) != receivenamel) error("lua: warning: symbol munged (contains \\0 in body)");
+            if (lua_isstring(L, 2)) 
+            {
+                selname = lua_tolstring(L, 2, &selnamel);
+                selsym = gensym((char *) selname); /* const cast */
+                if (selsym)
+                {
+                    if (strlen(selname) != selnamel) error("lua: warning: symbol munged (contains \\0 in body)");
+                    lua_pushvalue(L, 3);
+                    atoms = pdlua_popatomtable(L, &count, NULL);
+                    if ((count == 0 || atoms) && (receivesym->s_thing)) typedmess(receivesym->s_thing, selsym, count, atoms);
+                    else error("lua: error: no atoms??");
+                    if (atoms) 
+                    {
+                        free(atoms);
+                        PDLUA_DEBUG("pdlua_send: success end. stack top is %d", lua_gettop(L));
+                        return 0;
+                    }
+                }
+                else error("lua: error: null selector");
+            }
+            else error("lua: error: selector must be a string");
+        }
+        else error("lua: error: null receive name");
+    }
+    else error("lua: error: receive name must be string");
+    PDLUA_DEBUG("pdlua_send: fail end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Set a [value] object's value. */
+static int pdlua_setvalue(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Value name string.
+  * \li \c 2 Value number.
+  * \par Outputs:
+  * \li \c 1 success (usually depends on a [value] existing or not).
+  */
+{
+    const char  *str = luaL_checkstring(L, 1);
+    t_float     val = luaL_checknumber(L, 2);
+    int         err = value_setfloat(gensym(str), val);
+
+    PDLUA_DEBUG("pdlua_setvalue: stack top is %d", lua_gettop(L));
+    lua_pushboolean(L, !err);
+    PDLUA_DEBUG("pdlua_setvalue: end. stack top is %d", lua_gettop(L));
+    return 1;
+}
+
+/** Get a [value] object's value. */
+static int pdlua_getvalue(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Value name string.
+  * \par Outputs:
+  * \li \c 1 Value number, or nil for failure.
+  * */
+{
+    const char  *str = luaL_checkstring(L, 1);
+    t_float     val;
+    int         err = value_getfloat(gensym(str), &val);
+
+    PDLUA_DEBUG("pdlua_getvalue: stack top is %d", lua_gettop(L));
+    if (!err) lua_pushnumber(L, val);
+    else lua_pushnil(L);
+    PDLUA_DEBUG("pdlua_getvalue: end. stack top is %d", lua_gettop(L));
+    return 1;
+}
+
+/** Get a [table] object's array. */
+static int pdlua_getarray(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Table name string.
+  * \par Outputs:
+  * \li \c 1 Table length, or < 0 for failure.
+  * \li \c 2 Table pointer, or nil for failure.
+  * */
+{
+    t_garray        *a;
+    int             n;
+    PDLUA_ARRAYTYPE *v;
+    const char      *str = luaL_checkstring(L, 1);
+
+    PDLUA_DEBUG("pdlua_getarray: stack top is %d", lua_gettop(L));
+    if (!(a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) 
+    {
+        lua_pushnumber(L, -1);
+        PDLUA_DEBUG("pdlua_getarray: end 1. stack top is %d", lua_gettop(L));
+        return 1;
+    }
+    else if (!PDLUA_ARRAYGRAB(a, &n, &v)) 
+    {
+        lua_pushnumber(L, -2);
+        PDLUA_DEBUG("pdlua_getarray: end 2. stack top is %d", lua_gettop(L));
+        return 1;
+    }
+    else 
+    {
+        lua_pushnumber(L, n);
+        lua_pushlightuserdata(L, v);
+        PDLUA_DEBUG("pdlua_getarray: end 3. stack top is %d", lua_gettop(L));
+        return 2;
+    }
+}
+
+/** Read from a [table] object's array. */
+static int pdlua_readarray(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Table length number.
+  * \li \c 2 Table array pointer.
+  * \li \c 3 Table index number.
+  * \par Outputs:
+  * \li \c 1 Table element value, or nil for index out of range.
+  * */
+{
+    int             n = luaL_checknumber(L, 1);
+    PDLUA_ARRAYTYPE *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL;
+    int             i = luaL_checknumber(L, 3);
+
+    PDLUA_DEBUG("pdlua_readarray: stack top is %d", lua_gettop(L));
+    if (0 <= i && i < n && v) 
+    {
+        lua_pushnumber(L, PDLUA_ARRAYELEM(v, i));
+        PDLUA_DEBUG("pdlua_readarray: end 1. stack top is %d", lua_gettop(L));
+        return 1;
+    }
+    PDLUA_DEBUG("pdlua_readarray: end 2. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Write to a [table] object's array. */
+static int pdlua_writearray(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Table length number.
+  * \li \c 2 Table array pointer.
+  * \li \c 3 Table index number.
+  * \li \c 4 Table element value number.
+  * */
+{
+    int                 n = luaL_checknumber(L, 1);
+    PDLUA_ARRAYTYPE     *v = lua_islightuserdata(L, 2) ? lua_touserdata(L, 2) : NULL;
+    int                 i = luaL_checknumber(L, 3);
+    t_float             x = luaL_checknumber(L, 4);
+
+    PDLUA_DEBUG("pdlua_writearray: stack top is %d", lua_gettop(L));
+    if (0 <= i && i < n && v) PDLUA_ARRAYELEM(v, i) = x;
+    PDLUA_DEBUG("pdlua_writearray: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Redraw a [table] object's graph. */
+static int pdlua_redrawarray(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Table name string.
+  * */
+{
+    t_garray    *a;
+    const char  *str = luaL_checkstring(L, 1);
+
+    PDLUA_DEBUG("pdlua_redrawarray: stack top is %d", lua_gettop(L));
+    if ((a = (t_garray *) pd_findbyclass(gensym(str), garray_class))) garray_redraw(a);
+    PDLUA_DEBUG("pdlua_redrawarray: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Post to Pd's console. */
+static int pdlua_post(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Message string.
+  * */
+{
+    const char *str = luaL_checkstring(L, 1);
+    PDLUA_DEBUG("pdlua_post: stack top is %d", lua_gettop(L));
+    post("%s", str);
+    PDLUA_DEBUG("pdlua_post: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+/** Report an error from a Lua object to Pd's console. */
+static int pdlua_error(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * \li \c 2 Message string.
+  * */
+{
+    t_pdlua     *o;
+
+
+    const char  *s;
+
+    PDLUA_DEBUG("pdlua_error: stack top is %d", lua_gettop(L));
+    if (lua_islightuserdata(L, 1))
+    {
+        o = lua_touserdata(L, 1);
+        if (o)
+        {
+            s = luaL_checkstring(L, 2);
+            if (s) pd_error(o, "%s", s);
+            else pd_error(o, "lua: error: null string in error function");
+        }
+        else error("lua: error: null object in error function");
+    }
+    else error("lua: error: bad arguments to error function");
+    PDLUA_DEBUG("pdlua_error: end. stack top is %d", lua_gettop(L));
+    return 0;
+}
+
+static void pdlua_setrequirepath
+( /* FIXME: documentation (is this of any use at all?) */
+    lua_State   *L,
+    const char  *path
+)
+{
+    PDLUA_DEBUG("pdlua_setrequirepath: stack top %d", lua_gettop(L));
+    lua_getglobal(L, "pd");
+    lua_pushstring(L, "_setrequirepath");
+    lua_gettable(L, -2);
+    lua_pushstring(L, path);
+    if (lua_pcall(L, 1, 0, 0) != 0)
+    {
+        error("lua: internal error in `pd._setrequirepath': %s", lua_tostring(L, -1));
+        lua_pop(L, 1);
+    }
+    lua_pop(L, 1);
+    PDLUA_DEBUG("pdlua_setrequirepath: end. stack top %d", lua_gettop(L));
+}
+
+static void pdlua_clearrequirepath
+( /* FIXME: documentation (is this of any use at all?) */
+    lua_State *L
+)
+{
+    PDLUA_DEBUG("pdlua_clearrequirepath: stack top %d", lua_gettop(L));
+    lua_getglobal(L, "pd");
+    lua_pushstring(L, "_clearrequirepath");
+    lua_gettable(L, -2);
+    if (lua_pcall(L, 0, 0, 0) != 0)
+    {
+        error("lua: internal error in `pd._clearrequirepath': %s", lua_tostring(L, -1));
+        lua_pop(L, 1);
+    }
+    lua_pop(L, 1);
+    PDLUA_DEBUG("pdlua_clearrequirepath: end. stack top %d", lua_gettop(L));
+}
+
+/** Run a Lua script using Pd's path. */
+static int pdlua_dofile(lua_State *L)
+/**< Lua interpreter state.
+  * \par Inputs:
+  * \li \c 1 Pd object pointer.
+  * \li \c 2 Filename string.
+  * \par Outputs:
+  * \li \c * Determined by the script.
+  * */
+{
+    char                buf[MAXPDSTRING];
+    char                *ptr;
+    t_pdlua_readerdata  reader;
+    int                 fd;
+    int                 n;
+    const char          *filename;
+    t_pdlua             *o;
+
+    PDLUA_DEBUG("pdlua_dofile: stack top %d", lua_gettop(L));
+    n = lua_gettop(L);
+    if (lua_islightuserdata(L, 1))
+    {
+        o = lua_touserdata(L, 1);
+        if (o)
+        {
+            filename = luaL_optstring(L, 2, NULL);
+            fd = canvas_open(o->canvas, filename, "", buf, &ptr, MAXPDSTRING, 1);
+            if (fd >= 0)
+            {
+                PDLUA_DEBUG("pdlua_dofile path is %s", buf);
+                //pdlua_setpathname(o, buf);/* change the scriptname to include its path */
+                pdlua_setrequirepath(L, buf);
+                reader.fd = fd;
+#if LUA_VERSION_NUM	< 502
+                if (lua_load(L, pdlua_reader, &reader, filename))
+#else // 5.2 style
+                if (lua_load(L, pdlua_reader, &reader, filename, NULL))
+#endif // LUA_VERSION_NUM	< 502
+                {
+                    close(fd);
+                    pdlua_clearrequirepath(L);
+                    lua_error(L);
+                }
+                else
+                {
+                    if (lua_pcall(L, 0, LUA_MULTRET, 0))
+                    {
+                        pd_error(o, "lua: error running `%s':\n%s", filename, lua_tostring(L, -1));
+                        lua_pop(L, 1);
+                        close(fd);
+                        pdlua_clearrequirepath(L);
+                    }
+                    else
+                    {
+                        /* succeeded */
+                        close(fd);
+                        pdlua_clearrequirepath(L);
+                    }
+                }
+            }
+            else pd_error(o, "lua: error loading `%s': canvas_open() failed", filename);
+        }
+        else error("lua: error in object:dofile() - object is null");
+    }
+    else error("lua: error in object:dofile() - object is wrong type");
+    lua_pushstring(L, buf); /* return the path as well so we can open it later with pdlua_menu_open() */
+    PDLUA_DEBUG("pdlua_dofile end. stack top is %d", lua_gettop(L));
+    
+    return lua_gettop(L) - n;
+}
+
+/** Initialize the pd API for Lua. */
+static void pdlua_init(lua_State *L)
+/**< Lua interpreter state. */
+{
+    lua_newtable(L);
+    lua_setglobal(L, "pd");
+    lua_getglobal(L, "pd");
+    lua_pushstring(L, "_iswindows");
+#ifdef _WIN32
+    lua_pushboolean(L, 1);
+#else
+    lua_pushboolean(L, 0);
+#endif // _WIN32
+    lua_settable(L, -3);
+    lua_pushstring(L, "_register");
+    lua_pushcfunction(L, pdlua_class_new);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_create");
+    lua_pushcfunction(L, pdlua_object_new);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_createinlets");
+    lua_pushcfunction(L, pdlua_object_createinlets);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_createoutlets");
+    lua_pushcfunction(L, pdlua_object_createoutlets);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_destroy");
+    lua_pushcfunction(L, pdlua_object_free);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_outlet");
+    lua_pushcfunction(L, pdlua_outlet);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_createreceive");
+    lua_pushcfunction(L, pdlua_receive_new);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_receivefree");
+    lua_pushcfunction(L, pdlua_receive_free);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_createclock");
+    lua_pushcfunction(L, pdlua_clock_new);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_clockfree");
+    lua_pushcfunction(L, pdlua_clock_free);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_clockset");
+    lua_pushcfunction(L, pdlua_clock_set);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_clockunset");
+    lua_pushcfunction(L, pdlua_clock_unset);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_clockdelay");
+    lua_pushcfunction(L, pdlua_clock_delay);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_dofile");
+    lua_pushcfunction(L, pdlua_dofile);
+    lua_settable(L, -3);
+    lua_pushstring(L, "send");
+    lua_pushcfunction(L, pdlua_send);
+    lua_settable(L, -3);
+    lua_pushstring(L, "getvalue");
+    lua_pushcfunction(L, pdlua_getvalue);
+    lua_settable(L, -3);
+    lua_pushstring(L, "setvalue");
+    lua_pushcfunction(L, pdlua_setvalue);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_getarray");
+    lua_pushcfunction(L, pdlua_getarray);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_readarray");
+    lua_pushcfunction(L, pdlua_readarray);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_writearray");
+    lua_pushcfunction(L, pdlua_writearray);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_redrawarray");
+    lua_pushcfunction(L, pdlua_redrawarray);
+    lua_settable(L, -3);
+    lua_pushstring(L, "post");
+    lua_pushcfunction(L, pdlua_post);
+    lua_settable(L, -3);
+    lua_pushstring(L, "_error");
+    lua_pushcfunction(L, pdlua_error);
+    lua_settable(L, -3);
+    lua_pop(L, 1);
+    PDLUA_DEBUG("pdlua_init: end. stack top is %d", lua_gettop(L));
+}
+
+/** Pd loader hook for loading and executing Lua scripts. */
+static int pdlua_loader_fromfd
+(
+    int         fd, /**< file-descriptor of .pd_lua file */
+    const char *name, /**< The name of the script (without .pd_lua extension). */
+    const char *dirbuf /**< The name of the directory the .pd_lua files lives in */
+)
+{
+    t_pdlua_readerdata  reader;
+
+    PDLUA_DEBUG("pdlua_loader: stack top %d", lua_gettop(L));
+    class_set_extern_dir(gensym(dirbuf));
+    pdlua_setrequirepath(L, dirbuf);
+    reader.fd = fd;
+#if LUA_VERSION_NUM	< 502
+    if (lua_load(L, pdlua_reader, &reader, name) || lua_pcall(L, 0, 0, 0))
+#else // 5.2 style
+    if (lua_load(L, pdlua_reader, &reader, name, NULL) || lua_pcall(L, 0, 0, 0))
+#endif // LUA_VERSION_NUM	< 502
+    {
+      error("lua: error loading `%s':\n%s", name, lua_tostring(L, -1));
+      lua_pop(L, 1);
+      pdlua_clearrequirepath(L);
+      class_set_extern_dir(&s_);
+      PDLUA_DEBUG("pdlua_loader: script error end. stack top %d", lua_gettop(L));
+      return 0;
+    }
+    pdlua_clearrequirepath(L);
+    class_set_extern_dir(&s_);
+    PDLUA_DEBUG("pdlua_loader: end. stack top %d", lua_gettop(L));
+    return 1;
+}
+
+static int pdlua_loader_legacy
+(
+    t_canvas    *canvas, /**< Pd canvas to use to find the script. */
+    char        *name /**< The name of the script (without .pd_lua extension). */
+)
+{
+    char                dirbuf[MAXPDSTRING];
+    char                *ptr;
+    int                 fd;
+    int result = 0;
+
+    fd = canvas_open(canvas, name, ".pd_lua", dirbuf, &ptr, MAXPDSTRING, 1);
+    if (fd>=0)
+    {
+      result=pdlua_loader_fromfd(fd, name, dirbuf);
+      sys_close(fd);
+    }
+    return result;
+}
+
+static int pdlua_loader_pathwise
+(
+    t_canvas    *canvas, /**< Pd canvas to use to find the script. */
+    const char  *objectname, /**< The name of the script (without .pd_lua extension). */
+    const char  *path /**< The directory to search for the script */
+)
+{
+    char                dirbuf[MAXPDSTRING];
+    char                *ptr;
+    int                 fd;
+    int result = 0;
+
+    if(!path)
+    {
+      /* we already tried all paths, so skip this */
+      return 0;
+    }
+    fd = sys_trytoopenone(path, objectname, ".pd_lua",
+      dirbuf, &ptr, MAXPDSTRING, 1);
+    /* TODO: try loading <classname>/<classname>.pd_lua */
+    if (fd>=0)
+    {
+      result=pdlua_loader_fromfd(fd, objectname, dirbuf);
+      sys_close(fd);
+    }
+    return result;
+}
+
+
+
+/** Start the Lua runtime and register our loader hook. */
+#ifdef _WIN32
+__declspec(dllexport)
+#endif 
+void pdlua_setup(void)
+{
+    char                pd_lua_path[MAXPDSTRING];
+    t_pdlua_readerdata  reader;
+    int                 fd;
+    int                 result;
+    char*               pdluaver = "pdlua 0.7.3 (GPL) 2014-2016 Martin Peach et al., based on";
+    char*               luaver = "lua 0.6~svn (GPL) 2008 Claude Heiland-Allen <claude@mathr.co.uk>";
+    char                compiled[MAXPDSTRING];
+    char                luaversionStr[MAXPDSTRING];
+    const lua_Number    *luaversion = lua_version (NULL);
+    int                 lvm, lvl;
+
+#ifndef BUILD_DATE
+# define BUILD_DATE __DATE__" "__TIME__
+#endif
+
+    snprintf(compiled, MAXPDSTRING-1, "pdlua: compiled for pd-%d.%d on %s",
+             PD_MAJOR_VERSION, PD_MINOR_VERSION, BUILD_DATE);
+
+    lvm = (*luaversion)/100;
+    lvl = (*luaversion) - (100*lvm);
+    snprintf(luaversionStr, MAXPDSTRING-1, "Using lua version %d.%d", lvm, lvl);
+
+#if PD_MAJOR_VERSION==0 && PD_MINOR_VERSION<43
+    post(pdluaver);
+    post(luaver);
+    post(compiled);
+    post(luaversionStr);
+#else
+    logpost(NULL, 3, pdluaver);
+    logpost(NULL, 3, luaver);
+    logpost(NULL, 3, compiled);
+    logpost(NULL, 3, luaversionStr);
+#endif
+    pdlua_proxyinlet_setup();
+    PDLUA_DEBUG("pdlua pdlua_proxyinlet_setup done", 0);
+    pdlua_proxyreceive_setup();
+    PDLUA_DEBUG("pdlua pdlua_proxyreceive_setup done", 0);
+    pdlua_proxyclock_setup();
+    PDLUA_DEBUG("pdlua pdlua_proxyclock_setup done", 0);
+#if LUA_VERSION_NUM	< 502
+    L = lua_open();
+#else // 5.2 style
+    L = luaL_newstate();
+#endif // LUA_VERSION_NUM	< 502
+    PDLUA_DEBUG("pdlua lua_open done L = %p", L);
+    luaL_openlibs(L);
+    PDLUA_DEBUG("pdlua luaL_openlibs done", 0);
+    pdlua_init(L);
+    PDLUA_DEBUG("pdlua pdlua_init done", 0);
+    /* "pd.lua" is the Lua part of pdlua, want to keep the C part minimal */
+    /* canvas_open can't find pd.lua unless we give the path to pd beforehand like pd -path /usr/lib/extra/pdlua */
+    /* To avoid this we can use c_externdir from m_imp.h, struct _class: t_symbol *c_externdir; */
+    /* c_externdir is the directory the extern was loaded from and is also the directory contining pd.lua */
+    sprintf(pd_lua_path, "%s/pd.lua", pdlua_proxyinlet_class->c_externdir->s_name); /* the full path to pd.lua */
+    PDLUA_DEBUG("pd_lua_path %s", pd_lua_path);
+    fd = open(pd_lua_path, O_RDONLY);
+/*    fd = canvas_open(canvas_getcurrent(), "pd", ".lua", buf, &ptr, MAXPDSTRING, 1);  looks all over and rarely succeeds */
+    PDLUA_DEBUG ("pd.lua loaded from %s", pd_lua_path);
+    PDLUA_DEBUG("pdlua canvas_open done fd = %d", fd);
+    PDLUA_DEBUG("pdlua_setup: stack top %d", lua_gettop(L));
+    if (fd >= 0)
+    { /* pd.lua was opened */
+        reader.fd = fd;
+#if LUA_VERSION_NUM	< 502
+        result = lua_load(L, pdlua_reader, &reader, "pd.lua");
+#else // 5.2 style
+        result = lua_load(L, pdlua_reader, &reader, "pd.lua", NULL); // mode bt for binary or text
+#endif // LUA_VERSION_NUM	< 502
+        PDLUA_DEBUG ("pdlua lua_load returned %d", result);
+        if (0 == result)
+        {
+            result = lua_pcall(L, 0, 0, 0);
+            PDLUA_DEBUG ("pdlua lua_pcall returned %d", result);
+        }
+        if (0 != result)
+        //if (lua_load(L, pdlua_reader, &reader, "pd.lua") || lua_pcall(L, 0, 0, 0))
+        {
+            error("lua: error loading `pd.lua':\n%s", lua_tostring(L, -1));
+            error("lua: loader will not be registered!");
+            error("lua: (is `pd.lua' in Pd's path list?)");
+            lua_pop(L, 1);
+        }
+        else
+        {
+            int maj=0,min=0,bug=0;
+	    sys_getversion(&maj,&min,&bug);
+	    if((maj==0) && (min<47))
+	      /* before Pd<0.47, the loaders had to iterate over each path themselves */
+	      sys_register_loader((loader_t)pdlua_loader_legacy);
+	    else
+	      /* since Pd>=0.47, Pd tries the loaders for each path */
+	      sys_register_loader((loader_t)pdlua_loader_pathwise);
+        }
+	close(fd);
+    }
+    else
+    {
+        error("lua: error loading `pd.lua': canvas_open() failed");
+        error("lua: loader will not be registered!");
+    }
+    PDLUA_DEBUG("pdlua_setup: end. stack top %d", lua_gettop(L));
+
+}
+
+/* EOF */
diff --git a/src/pdluax-help.pd b/pdluax-help.pd
similarity index 100%
rename from src/pdluax-help.pd
rename to pdluax-help.pd
diff --git a/src/Doxyfile b/src/Doxyfile
deleted file mode 100644
index 50a8de044258e6201febf58e874aa0483020b51b..0000000000000000000000000000000000000000
--- a/src/Doxyfile
+++ /dev/null
@@ -1,1252 +0,0 @@
-# Doxyfile 1.5.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = pdlua
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 0.6
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = ../doc
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
-# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
-# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
-# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
-# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE        = English
-
-# This tag can be used to specify the encoding used in the generated output. 
-# The encoding is not always determined by the language that is chosen, 
-# but also whether or not the output is meant for Windows or non-Windows users. 
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
-# forces the Windows encoding (this is the default for the Windows binary), 
-# whereas setting the tag to NO uses a Unix-style encoding (the default for 
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING   = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF       = 
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
-# path to strip.
-
-STRIP_FROM_PATH        = 
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH    = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like the Qt-style comments (thus requiring an 
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF      = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP         = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# re-implements.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 8
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for Java. 
-# For instance, namespaces will be presented as packages, qualified scopes 
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
-# include (a tag file for) the STL sources as input, then you should 
-# set this tag to YES in order to let doxygen match functions declarations and 
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
-# func(std::string) {}). This also make the inheritance and collaboration 
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT    = NO
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
-# the \nosubgrouping command.
-
-SUBGROUPING            = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES       = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
-# declaration order.
-
-SORT_BRIEF_DOCS        = YES
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the 
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES       = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from the 
-# version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the program writes to standard output 
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
-# documentation.
-
-WARN_NO_PARAMDOC       = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT                  = "lua.c"
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
-
-FILE_PATTERNS          = 
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
-# directories that are symbolic links (a Unix filesystem feature) are excluded 
-# from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
-# ignored.
-
-INPUT_FILTER           = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
-# is applied to all files.
-
-FILTER_PATTERNS        = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER         = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.  Otherwise they will link to the documentstion.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
-# will need version 4.8.6 or higher.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET        = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output directory.
-
-CHM_FILE               = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION           = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
-# in the output.
-
-LATEX_HIDE_INDICES     = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
-# instead of the = operator.
-
-PREDEFINED             = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse 
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option is superseded by the HAVE_DOT option below. This is only a 
-# fallback. It is recommended to install and use dot, since it yields more 
-# powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = YES
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
-# Language.
-
-UML_LOOK               = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
-# generate a call dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable call graphs for selected 
-# functions only using the \callgraph command.
-
-CALL_GRAPH             = YES
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
-# generate a caller dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable caller graphs for selected 
-# functions only using the \callergraph command.
-
-CALLER_GRAPH           = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT       = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_WIDTH    = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT   = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that a graph may be further truncated if the graph's 
-# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
-# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
-# the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, which results in a white background. 
-# Warning: Depending on the platform used, enabling this option may lead to 
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
-# read).
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
diff --git a/src/config.h b/src/config.h
deleted file mode 100644
index ed61e3138873e4bd6b6542786f65fbb89287261e..0000000000000000000000000000000000000000
--- a/src/config.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* src/config.h.  Generated from config.h.in by configure.  */
-/* src/config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
-   to 0 otherwise. */
-#define HAVE_MALLOC 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-/* Name of package */
-#define PACKAGE "pdlua"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "martin.peach@sympatico.ca"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "pdlua"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "pdlua 0.1"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "pdlua"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.1"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "0.6"
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to rpl_malloc if the replacement function should be used. */
-/* #undef malloc */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef ssize_t */