diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./config/configure.in ./config/configure.in
--- ./config/configure.in	2006-02-26 16:50:54.000000000 +0100
+++ ./config/configure.in	2006-03-16 23:08:07.000000000 +0100
@@ -253,6 +253,9 @@
 BZIP2=yes
 AC_ARG_ENABLE(bzip2,       [  --disable-bzip2         disable the use of bzip2], [BZIP2="$enableval"])
 
+MAGIC=yes
+AC_ARG_ENABLE(magic,       [  --disable-magic         disable the use of libmagic (GNU file)], [MAGIC="$enableval"])
+
 ifelse(AC_ACVERSION, [2.13], [],
 [dnl Large file enabled
    AC_SYS_LARGEFILE
@@ -592,6 +595,16 @@
   AC_DEFINE(USE_BZIP2, 1, [Define to 1 if you have bzip2 support.])
 fi
 
+if test "$MAGIC" != "no"; then
+  AC_CHECK_HEADERS(magic.h,[AC_CHECK_LIB(magic,magic_file,[MAGIC=yes],[MAGIC=no])],[MAGIC=no])
+fi
+
+if test "$MAGIC" = "yes"; then
+  MAGICLIB=Magic_magic
+else
+  MAGICLIB=Magic_nomagic
+fi
+
 AC_CHECK_HEADERS(byteswap.h,,)
 
 if test "$ICONV" = "yes"; then
@@ -1236,6 +1249,8 @@
 AC_SUBST(GD_CFLAGS)
 AC_SUBST(GD_LDFLAGS)
 AC_SUBST(BZIP2)
+AC_SUBST(MAGIC)
+AC_SUBST(MAGICLIB)
 
 BUILD_SYSTEM="`uname -s` `uname -m` `uname -r`"
 AC_SUBST(BUILD_SYSTEM)
@@ -1251,6 +1266,7 @@
   Makefile.config \
   mldonkey.rc \
   $AUTOCONF.new $GTK_AUTOCONF.new \
+   ../src/utils/lib/magic.ml \
    ../src/networks/donkey/donkeySui.ml \
    ../src/daemon/driver/driverGraphics.ml \
    ../packages/rpm/mldonkey.spec \
@@ -1370,6 +1386,13 @@
   echo "        disabled"
 fi
 
+echo -n " - libmagic          "
+if test "$MAGIC" = "yes"; then
+  echo "enabled"
+else
+  echo "        disabled"
+fi
+
 echo -n " - graphical stats   "
 if test "$GD" = "yes"; then
   echo "enabled"
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./config/Makefile.config.in ./config/Makefile.config.in
--- ./config/Makefile.config.in	2006-02-11 20:52:57.000000000 +0100
+++ ./config/Makefile.config.in	2006-03-16 22:09:36.000000000 +0100
@@ -50,6 +50,7 @@
 GLIBC_VERSION=@GLIBC_VERSION@
 ICONV=@ICONV@
 BZIP2=@BZIP2@
+MAGIC=@MAGIC@
 
 GD=@GD@
 GD_JPG=@GD_JPG@
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./config/Makefile.in ./config/Makefile.in
--- ./config/Makefile.in	2006-03-08 21:58:22.000000000 +0100
+++ ./config/Makefile.in	2006-03-16 22:50:16.000000000 +0100
@@ -193,6 +193,14 @@
   $(LIB)/stubs_c.c  $(LIB)/set2.ml $(LIB)/queues.ml \
   $(LIB)/charsetstubs.c $(LIB)/charset.ml
 
+ifeq ("$(MAGIC)", "yes")
+  LIBS_flags += -cclib -lmagic
+  LIB_SRCS += $(LIB)/swig.ml $(LIB)/magiclib.ml $(LIB)/magic_magic.ml $(LIB)/magiclib_wrap.c
+else
+  LIB_SRCS += $(LIB)/magic_nomagic.ml
+endif
+LIB_SRCS += $(LIB)/magic.ml
+
 NET_SRCS = \
   $(NET)/basicSocket.ml \
   $(NET)/ip.ml $(NET)/ip_set.ml $(NET)/geoip.ml $(NET)/mailer.ml $(NET)/base64.ml  \
@@ -220,6 +228,7 @@
 RSS_SRCS= \
   $(RSS)/rss_messages.ml $(RSS)/rss_types.ml  $(RSS)/rss_io.ml  $(RSS)/rss.ml
 
+
 COMMON_SRCS = \
   $(XML_SRCS) $(RSS_SRCS) \
   $(COMMON)/commonTypes.ml \
@@ -1698,6 +1707,7 @@
 	rm -f src/utils/lib/autoconf.ml.new
 	rm -f src/utils/lib/gAutoconf.ml
 	rm -f src/utils/lib/gAutoconf.ml.new
+	rm -f src/utils/lib/magic.ml
 	rm -f src/utils/lib/misc2.ml
 	rm -f src/utils/cdk/tar.ml
 	rm -f icons/tux/*.ml_icons
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/daemon/driver/driverCommands.ml ./src/daemon/driver/driverCommands.ml
--- ./src/daemon/driver/driverCommands.ml	2006-03-15 21:56:43.000000000 +0100
+++ ./src/daemon/driver/driverCommands.ml	2006-03-16 23:04:53.000000000 +0100
@@ -1981,6 +1981,16 @@
          _s ""
      ), "debug command (example: disk .)";
 
+     "debug_dir", Arg_one (fun arg o ->
+         let buf = o.conn_buf in
+	 let filelist = Unix2.list_directory arg in
+         Printf.bprintf buf "%d entries in dir %s\n" (List.length filelist) arg;
+	 List.iter (fun file ->
+           Printf.bprintf buf "%s %s\n" file (Magic.M.magic_fileinfo (Filename.concat arg file));
+	 ) filelist;
+         _s ""
+     ), "debug command (example: disk .)";
+
      "debug_fileinfo", Arg_one (fun arg o ->
          let buf = o.conn_buf in
 	 (try
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/daemon/driver/driverInteractive.ml ./src/daemon/driver/driverInteractive.ml
--- ./src/daemon/driver/driverInteractive.ml	2006-02-26 17:23:55.000000000 +0100
+++ ./src/daemon/driver/driverInteractive.ml	2006-03-16 21:52:14.000000000 +0100
@@ -1719,6 +1719,7 @@
 	  ^ (if Autoconf.has_gd && not Autoconf.has_gd_png && Autoconf.has_gd_jpg then " gd(jpg)" else "")
 	  ^ (if not Autoconf.has_gd then " no-gd" else "")
           ^ (if Autoconf.has_iconv then " iconv" else " no-iconv")
+          ^ (if Autoconf.magic then " magic" else " no-magic")
           ^ (if Autoconf.check_bounds then " check-bounds" else " no-check-bounds")
   )
   in
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/autoconf.ml.new.in ./src/utils/lib/autoconf.ml.new.in
--- ./src/utils/lib/autoconf.ml.new.in	2006-01-26 01:25:25.000000000 +0100
+++ ./src/utils/lib/autoconf.ml.new.in	2006-03-16 20:45:35.000000000 +0100
@@ -44,6 +44,7 @@
 let has_gd_jpg = if "@GD_JPG@" = "yes" then true else false
 
 let bzip2 = if "@BZIP2@" = "yes" then true else false
+let magic = if "@MAGIC@" = "yes" then true else false
 
 let zlib__uncompress_string2 s = Zlib.uncompress_string2 s
 let zlib__compress_string s = Zlib.compress_string s
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/magiclib.ml ./src/utils/lib/magiclib.ml
--- ./src/utils/lib/magiclib.ml	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/magiclib.ml	2006-03-16 22:31:06.000000000 +0100
@@ -0,0 +1,112 @@
+open Swig
+type c_enum_type = [ 
+  `unknown
+]
+type c_enum_value = [ 
+  `Int of int
+]
+
+type c_obj = c_enum_value c_obj_t
+let module_name = "magiclib"
+
+exception BadArgs of string
+exception BadMethodName of c_obj * string * string
+exception NotObject of c_obj
+exception NotEnumType of c_obj
+exception LabelNotFromThisEnum of c_obj
+exception InvalidDirectorCall of c_obj
+
+external _MAGIC_NONE : c_obj -> Swig.c_obj = "_wrap_MAGIC_NONE" 
+external _MAGIC_DEBUG : c_obj -> Swig.c_obj = "_wrap_MAGIC_DEBUG" 
+external _MAGIC_SYMLINK : c_obj -> Swig.c_obj = "_wrap_MAGIC_SYMLINK" 
+external _MAGIC_COMPRESS : c_obj -> Swig.c_obj = "_wrap_MAGIC_COMPRESS" 
+external _MAGIC_DEVICES : c_obj -> Swig.c_obj = "_wrap_MAGIC_DEVICES" 
+external _MAGIC_MIME : c_obj -> Swig.c_obj = "_wrap_MAGIC_MIME" 
+external _MAGIC_CONTINUE : c_obj -> Swig.c_obj = "_wrap_MAGIC_CONTINUE" 
+external _MAGIC_CHECK : c_obj -> Swig.c_obj = "_wrap_MAGIC_CHECK" 
+external _MAGIC_PRESERVE_ATIME : c_obj -> Swig.c_obj = "_wrap_MAGIC_PRESERVE_ATIME" 
+external _MAGIC_RAW : c_obj -> Swig.c_obj = "_wrap_MAGIC_RAW" 
+external _MAGIC_ERROR : c_obj -> Swig.c_obj = "_wrap_MAGIC_ERROR" 
+external _magic_open_f : c_obj list -> c_obj list = "_wrap_magic_openmagiclib" ;;
+let _magic_open arg = match _magic_open_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_close_f : c_obj list -> c_obj list = "_wrap_magic_closemagiclib" ;;
+let _magic_close arg = match _magic_close_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_file_f : c_obj list -> c_obj list = "_wrap_magic_filemagiclib" ;;
+let _magic_file arg = match _magic_file_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_buffer_f : c_obj list -> c_obj list = "_wrap_magic_buffermagiclib" ;;
+let _magic_buffer arg = match _magic_buffer_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_error_f : c_obj list -> c_obj list = "_wrap_magic_errormagiclib" ;;
+let _magic_error arg = match _magic_error_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_setflags_f : c_obj list -> c_obj list = "_wrap_magic_setflagsmagiclib" ;;
+let _magic_setflags arg = match _magic_setflags_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_load_f : c_obj list -> c_obj list = "_wrap_magic_loadmagiclib" ;;
+let _magic_load arg = match _magic_load_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_compile_f : c_obj list -> c_obj list = "_wrap_magic_compilemagiclib" ;;
+let _magic_compile arg = match _magic_compile_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_check_f : c_obj list -> c_obj list = "_wrap_magic_checkmagiclib" ;;
+let _magic_check arg = match _magic_check_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external _magic_errno_f : c_obj list -> c_obj list = "_wrap_magic_errnomagiclib" ;;
+let _magic_errno arg = match _magic_errno_f (fnhelper arg) with
+  [] -> C_void
+| [x] -> (if false then Gc.finalise 
+  (fun x -> ignore ((invoke x) "~" C_void)) x) ; x
+| lst -> C_list lst ;;
+external f_init : unit -> unit = "f_magiclib_init" ;;
+let _ = f_init ()
+let enum_to_int x (v : c_obj) =
+   match v with
+     C_enum _y ->
+     (let y = _y in match (x : c_enum_type) with
+       `unknown ->          (match y with
+           `Int x -> (Swig.C_int x)
+           | _ -> raise (LabelNotFromThisEnum v))
+) | _ -> (C_int (get_int v))
+let _ = Callback.register "magiclib_enum_to_int" enum_to_int
+let int_to_enum x y =
+    match (x : c_enum_type) with
+      `unknown -> C_enum (`Int y)
+let _ = Callback.register "magiclib_int_to_enum" int_to_enum
+
+  let rec swig_val t v = 
+    match v with
+        C_enum e -> enum_to_int t v
+      | C_list l -> Swig.C_list (List.map (swig_val t) l)
+      | C_array a -> Swig.C_array (Array.map (swig_val t) a)
+      | _ -> Obj.magic v
+
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/magiclib.mli ./src/utils/lib/magiclib.mli
--- ./src/utils/lib/magiclib.mli	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/magiclib.mli	2006-03-16 22:31:06.000000000 +0100
@@ -0,0 +1,44 @@
+open Swig
+type c_enum_type = [ 
+  `unknown
+]
+type c_enum_value = [ 
+  `Int of int
+]
+
+type c_obj = c_enum_value c_obj_t
+val module_name : string
+
+exception BadArgs of string
+exception BadMethodName of c_obj * string * string
+exception NotObject of c_obj
+exception NotEnumType of c_obj
+exception LabelNotFromThisEnum of c_obj
+exception InvalidDirectorCall of c_obj
+
+val _MAGIC_NONE : c_obj -> Swig.c_obj
+val _MAGIC_DEBUG : c_obj -> Swig.c_obj
+val _MAGIC_SYMLINK : c_obj -> Swig.c_obj
+val _MAGIC_COMPRESS : c_obj -> Swig.c_obj
+val _MAGIC_DEVICES : c_obj -> Swig.c_obj
+val _MAGIC_MIME : c_obj -> Swig.c_obj
+val _MAGIC_CONTINUE : c_obj -> Swig.c_obj
+val _MAGIC_CHECK : c_obj -> Swig.c_obj
+val _MAGIC_PRESERVE_ATIME : c_obj -> Swig.c_obj
+val _MAGIC_RAW : c_obj -> Swig.c_obj
+val _MAGIC_ERROR : c_obj -> Swig.c_obj
+val _magic_open : c_obj -> c_obj
+val _magic_close : c_obj -> c_obj
+val _magic_file : c_obj -> c_obj
+val _magic_buffer : c_obj -> c_obj
+val _magic_error : c_obj -> c_obj
+val _magic_setflags : c_obj -> c_obj
+val _magic_load : c_obj -> c_obj
+val _magic_compile : c_obj -> c_obj
+val _magic_check : c_obj -> c_obj
+val _magic_errno : c_obj -> c_obj
+val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj
+val int_to_enum : c_enum_type -> int -> c_obj
+
+  val swig_val : c_enum_type -> c_obj -> Swig.c_obj
+
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/magiclib_wrap.c ./src/utils/lib/magiclib_wrap.c
--- ./src/utils/lib/magiclib_wrap.c	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/magiclib_wrap.c	2006-03-16 22:31:06.000000000 +0100
@@ -0,0 +1,1864 @@
+/* -*- buffer-read-only: t -*- vi: set ro: */
+#define SWIG_MODULE "magiclib"
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.25
+ * 
+ * This file is not intended to be easily readable and contains a number of 
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG 
+ * interface file instead. 
+ * ----------------------------------------------------------------------------- */
+
+/***********************************************************************
+ *
+ *  This section contains generic SWIG labels for method/variable
+ *  declarations/attributes, and other compiler dependent labels.
+ *
+ ************************************************************************/
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+#  if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+#    define SWIGTEMPLATEDISAMBIGUATOR template
+#  else
+#    define SWIGTEMPLATEDISAMBIGUATOR 
+#  endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+#   define SWIGINLINE inline
+# else
+#   define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__) || defined(__ICC)
+#   define SWIGUNUSED __attribute__ ((unused)) 
+# else
+#   define SWIGUNUSED 
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods for Windows DLLs */
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#   if defined(STATIC_LINKED)
+#     define SWIGEXPORT
+#   else
+#     define SWIGEXPORT __declspec(dllexport)
+#   endif
+# else
+#   define SWIGEXPORT
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#   define SWIGSTDCALL __stdcall
+# else
+#   define SWIGSTDCALL
+# endif 
+#endif
+
+
+
+#define SWIGSTATIC static
+
+/***********************************************************************
+ * swigrun.swg
+ *
+ *     This file contains generic CAPI SWIG runtime support for pointer
+ *     type checking.
+ *
+ ************************************************************************/
+
+/* This should only be incremented when either the layout of swig_type_info changes,
+   or for whatever reason, the runtime changes incompatibly */
+#define SWIG_RUNTIME_VERSION "2"
+
+/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
+#ifdef SWIG_TYPE_TABLE
+# define SWIG_QUOTE_STRING(x) #x
+# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
+# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
+#else
+# define SWIG_TYPE_TABLE_NAME
+#endif
+
+/*
+  You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
+  creating a static or dynamic library from the swig runtime code.
+  In 99.9% of the cases, swig just needs to declare them as 'static'.
+  
+  But only do this if is strictly necessary, ie, if you have problems
+  with your compiler or so.
+*/
+
+#ifndef SWIGRUNTIME
+# define SWIGRUNTIME SWIGINTERN
+#endif
+
+#ifndef SWIGRUNTIMEINLINE
+# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
+#endif
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *(*swig_converter_func)(void *);
+typedef struct swig_type_info *(*swig_dycast_func)(void **);
+
+/* Structure to store inforomation on one type */
+typedef struct swig_type_info {
+  const char             *name;			/* mangled name of this type */
+  const char             *str;			/* human readable name of this type */
+  swig_dycast_func        dcast;		/* dynamic cast function down a hierarchy */
+  struct swig_cast_info  *cast;			/* linked list of types that can cast into this type */
+  void                   *clientdata;		/* language specific type data */
+} swig_type_info;
+
+/* Structure to store a type and conversion function used for casting */
+typedef struct swig_cast_info {
+  swig_type_info         *type;			/* pointer to type that is equivalent to this type */
+  swig_converter_func     converter;		/* function to cast the void pointers */
+  struct swig_cast_info  *next;			/* pointer to next cast in linked list */
+  struct swig_cast_info  *prev;			/* pointer to the previous cast */
+} swig_cast_info;
+
+/* Structure used to store module information
+ * Each module generates one structure like this, and the runtime collects
+ * all of these structures and stores them in a circularly linked list.*/
+typedef struct swig_module_info {
+  swig_type_info         **types;		/* Array of pointers to swig_type_info structures that are in this module */
+  size_t                 size;		        /* Number of types in this module */
+  struct swig_module_info *next;		/* Pointer to next element in circularly linked list */
+  swig_type_info         **type_initial;	/* Array of initially generated type structures */
+  swig_cast_info         **cast_initial;	/* Array of initially generated casting structures */
+  void                    *clientdata;		/* Language specific module data */
+} swig_module_info;
+
+
+/* 
+  Compare two type names skipping the space characters, therefore
+  "char*" == "char *" and "Class<int>" == "Class<int >", etc.
+
+  Return 0 when the two name types are equivalent, as in
+  strncmp, but skipping ' '.
+*/
+SWIGRUNTIME int
+SWIG_TypeNameComp(const char *f1, const char *l1,
+		  const char *f2, const char *l2) {
+  for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
+    while ((*f1 == ' ') && (f1 != l1)) ++f1;
+    while ((*f2 == ' ') && (f2 != l2)) ++f2;
+    if (*f1 != *f2) return (int)(*f1 - *f2);
+  }
+  return (l1 - f1) - (l2 - f2);
+}
+
+/*
+  Check type equivalence in a name list like <name1>|<name2>|...
+  Return 0 if not equal, 1 if equal
+*/
+SWIGRUNTIME int
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+  int equiv = 0;
+  const char* te = tb + strlen(tb);
+  const char* ne = nb;
+  while (!equiv && *ne) {
+    for (nb = ne; *ne; ++ne) {
+      if (*ne == '|') break;
+    }
+    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+    if (*ne) ++ne;
+  }
+  return equiv;
+}
+
+/*
+  Check type equivalence in a name list like <name1>|<name2>|...
+  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+*/
+SWIGRUNTIME int
+SWIG_TypeCompare(const char *nb, const char *tb) {
+  int equiv = 0;
+  const char* te = tb + strlen(tb);
+  const char* ne = nb;
+  while (!equiv && *ne) {
+    for (nb = ne; *ne; ++ne) {
+      if (*ne == '|') break;
+    }
+    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+    if (*ne) ++ne;
+  }
+  return equiv;
+}
+
+
+/* think of this as a c++ template<> or a scheme macro */
+#define SWIG_TypeCheck_Template(comparison, ty)         \
+  if (ty) {                                             \
+    swig_cast_info *iter = ty->cast;                    \
+    while (iter) {                                      \
+      if (comparison) {                                 \
+        if (iter == ty->cast) return iter;              \
+        /* Move iter to the top of the linked list */   \
+        iter->prev->next = iter->next;                  \
+        if (iter->next)                                 \
+          iter->next->prev = iter->prev;                \
+        iter->next = ty->cast;                          \
+        iter->prev = 0;                                 \
+        if (ty->cast) ty->cast->prev = iter;            \
+        ty->cast = iter;                                \
+        return iter;                                    \
+      }                                                 \
+      iter = iter->next;                                \
+    }                                                   \
+  }                                                     \
+  return 0
+
+/*
+  Check the typename
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheck(const char *c, swig_type_info *ty) {
+  SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty);
+}
+
+/* Same as previous function, except strcmp is replaced with a pointer comparison */
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
+  SWIG_TypeCheck_Template(iter->type == from, into);
+}
+
+/*
+  Cast a pointer up an inheritance hierarchy
+*/
+SWIGRUNTIMEINLINE void *
+SWIG_TypeCast(swig_cast_info *ty, void *ptr) {
+  return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
+}
+
+/* 
+   Dynamic pointer casting. Down an inheritance hierarchy
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
+  swig_type_info *lastty = ty;
+  if (!ty || !ty->dcast) return ty;
+  while (ty && (ty->dcast)) {
+    ty = (*ty->dcast)(ptr);
+    if (ty) lastty = ty;
+  }
+  return lastty;
+}
+
+/*
+  Return the name associated with this type
+*/
+SWIGRUNTIMEINLINE const char *
+SWIG_TypeName(const swig_type_info *ty) {
+  return ty->name;
+}
+
+/*
+  Return the pretty name associated with this type,
+  that is an unmangled type name in a form presentable to the user.
+*/
+SWIGRUNTIME const char *
+SWIG_TypePrettyName(const swig_type_info *type) {
+  /* The "str" field contains the equivalent pretty names of the
+     type, separated by vertical-bar characters.  We choose
+     to print the last name, as it is often (?) the most
+     specific. */
+  if (type->str != NULL) {
+    const char *last_name = type->str;
+    const char *s;
+    for (s = type->str; *s; s++)
+      if (*s == '|') last_name = s+1;
+    return last_name;
+  }
+  else
+    return type->name;
+}
+
+/* 
+   Set the clientdata field for a type
+*/
+SWIGRUNTIME void
+SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
+  if (!ti->clientdata) {
+    swig_cast_info *cast = ti->cast;
+    /* if (ti->clientdata == clientdata) return; */
+    ti->clientdata = clientdata;
+    
+    while (cast) {
+      if (!cast->converter)
+	SWIG_TypeClientData(cast->type, clientdata);
+      cast = cast->next;
+    }
+  }
+}
+
+/*
+  Search for a swig_type_info structure only by mangled name
+  Search is a O(log #types)
+  
+  We start searching at module start, and finish searching when start == end.  
+  Note: if start == end at the beginning of the function, we go all the way around
+  the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_MangledTypeQueryModule(swig_module_info *start, 
+                            swig_module_info *end, 
+		            const char *name) {
+  swig_module_info *iter = start;
+  do {
+    if (iter->size) {
+      register size_t l = 0;
+      register size_t r = iter->size - 1;
+      do {
+	/* since l+r >= 0, we can (>> 1) instead (/ 2) */
+	register size_t i = (l + r) >> 1; 
+	const char *iname = iter->types[i]->name;
+	if (iname) {
+	  register int compare = strcmp(name, iname);
+	  if (compare == 0) {	    
+	    return iter->types[i];
+	  } else if (compare < 0) {
+	    if (i) {
+	      r = i - 1;
+	    } else {
+	      break;
+	    }
+	  } else if (compare > 0) {
+	    l = i + 1;
+	  }
+	} else {
+	  break; /* should never happen */
+	}
+      } while (l <= r);
+    }
+    iter = iter->next;
+  } while (iter != end);
+  return 0;
+}
+
+/*
+  Search for a swig_type_info structure for either a mangled name or a human readable name.
+  It first searches the mangled names of the types, which is a O(log #types)
+  If a type is not found it then searches the human readable names, which is O(#types).
+  
+  We start searching at module start, and finish searching when start == end.  
+  Note: if start == end at the beginning of the function, we go all the way around
+  the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeQueryModule(swig_module_info *start, 
+                     swig_module_info *end, 
+		     const char *name) {
+  /* STEP 1: Search the name field using binary search */
+  swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
+  if (ret) {
+    return ret;
+  } else {
+    /* STEP 2: If the type hasn't been found, do a complete search
+       of the str field (the human readable name) */
+    swig_module_info *iter = start;
+    do {
+      register size_t i = 0;
+      for (; i < iter->size; ++i) {
+	if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
+	  return iter->types[i];
+      }
+      iter = iter->next;
+    } while (iter != end);
+  }
+  
+  /* neither found a match */
+  return 0;
+}
+
+
+/* 
+   Pack binary data into a string
+*/
+SWIGRUNTIME char *
+SWIG_PackData(char *c, void *ptr, size_t sz) {
+  static const char hex[17] = "0123456789abcdef";
+  register const unsigned char *u = (unsigned char *) ptr;
+  register const unsigned char *eu =  u + sz;
+  for (; u != eu; ++u) {
+    register unsigned char uu = *u;
+    *(c++) = hex[(uu & 0xf0) >> 4];
+    *(c++) = hex[uu & 0xf];
+  }
+  return c;
+}
+
+/* 
+   Unpack binary data from a string
+*/
+SWIGRUNTIME const char *
+SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
+  register unsigned char *u = (unsigned char *) ptr;
+  register const unsigned char *eu = u + sz;
+  for (; u != eu; ++u) {
+    register char d = *(c++);
+    register unsigned char uu = 0;
+    if ((d >= '0') && (d <= '9'))
+      uu = ((d - '0') << 4);
+    else if ((d >= 'a') && (d <= 'f'))
+      uu = ((d - ('a'-10)) << 4);
+    else 
+      return (char *) 0;
+    d = *(c++);
+    if ((d >= '0') && (d <= '9'))
+      uu |= (d - '0');
+    else if ((d >= 'a') && (d <= 'f'))
+      uu |= (d - ('a'-10));
+    else 
+      return (char *) 0;
+    *u = uu;
+  }
+  return c;
+}
+
+/* 
+   Pack 'void *' into a string buffer.
+*/
+SWIGRUNTIME char *
+SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
+  char *r = buff;
+  if ((2*sizeof(void *) + 2) > bsz) return 0;
+  *(r++) = '_';
+  r = SWIG_PackData(r,&ptr,sizeof(void *));
+  if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
+  strcpy(r,name);
+  return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
+  if (*c != '_') {
+    if (strcmp(c,"NULL") == 0) {
+      *ptr = (void *) 0;
+      return name;
+    } else {
+      return 0;
+    }
+  }
+  return SWIG_UnpackData(++c,ptr,sizeof(void *));
+}
+
+SWIGRUNTIME char *
+SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
+  char *r = buff;
+  size_t lname = (name ? strlen(name) : 0);
+  if ((2*sz + 2 + lname) > bsz) return 0;
+  *(r++) = '_';
+  r = SWIG_PackData(r,ptr,sz);
+  if (lname) {
+    strncpy(r,name,lname+1);
+  } else {
+    *r = 0;
+  }
+  return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
+  if (*c != '_') {
+    if (strcmp(c,"NULL") == 0) {
+      memset(ptr,0,sz);
+      return name;
+    } else {
+      return 0;
+    }
+  }
+  return SWIG_UnpackData(++c,ptr,sz);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* -*-c-*-
+ * -----------------------------------------------------------------------
+ * ocaml/ocamldec.swg
+ * Copyright (C) 2000, 2001 Matthias Koeppe
+ *
+ * Ocaml runtime code -- declarations
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+#define SWIGEXT extern "C"
+SWIGEXT {
+#else
+#define SWIGEXT 
+#endif
+#define value caml_value_t
+#define CAML_VALUE caml_value_t
+#include <caml/alloc.h>
+#include <caml/custom.h>
+#include <caml/mlvalues.h>
+#include <caml/memory.h>
+#include <caml/callback.h>
+#include <caml/fail.h>
+#include <caml/misc.h>
+
+#define caml_array_set swig_caml_array_set
+
+// Adapted from memory.h and mlvalues.h
+
+#define SWIG_CAMLlocal1(x) \
+  caml_value_t x = 0; \
+  CAMLxparam1 (x)
+
+#define SWIG_CAMLlocal2(x, y) \
+  caml_value_t x = 0, y = 0; \
+  CAMLxparam2 (x, y)
+
+#define SWIG_CAMLlocal3(x, y, z) \
+  caml_value_t x = 0, y = 0, z = 0; \
+  CAMLxparam3 (x, y, z)
+
+#define SWIG_CAMLlocal4(x, y, z, t) \
+  caml_value_t x = 0, y = 0, z = 0, t = 0; \
+  CAMLxparam4 (x, y, z, t)
+
+#define SWIG_CAMLlocal5(x, y, z, t, u) \
+  caml_value_t x = 0, y = 0, z = 0, t = 0, u = 0; \
+  CAMLxparam5 (x, y, z, t, u)
+
+#define SWIG_CAMLlocalN(x, size) \
+  caml_value_t x [(size)] = { 0, /* 0, 0, ... */ }; \
+  CAMLxparamN (x, (size))
+
+#define SWIG_Field(x, i) (((caml_value_t *)(x)) [i])           /* Also an l-value. */
+#define SWIG_Store_field(block, offset, val) do{ \
+  mlsize_t caml__temp_offset = (offset); \
+  caml_value_t caml__temp_val = (val); \
+  modify (&SWIG_Field ((block), caml__temp_offset), caml__temp_val); \
+}while(0)
+
+#define SWIG_Data_custom_val(v) ((void *) &SWIG_Field((v), 1))
+#ifdef ARCH_BIG_ENDIAN
+#define SWIG_Tag_val(val) (((unsigned char *) (val)) [-1])
+                                                 /* Also an l-value. */
+#define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [sizeof(caml_value_t)-1])
+                                                 /* Also an l-value. */
+#else
+#define SWIG_Tag_val(val) (((unsigned char *) (val)) [-sizeof(caml_value_t)])
+                                                 /* Also an l-value. */
+#define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [0])
+                                                 /* Also an l-value. */
+#endif
+
+#ifndef ARCH_ALIGN_INT64
+#define SWIG_Int64_val(v) (*((int64 *) SWIG_Data_custom_val(v)))
+#else
+CAMLextern int64 Int64_val(caml_value_t v);
+#define SWIG_Int64_val(v) Int64_val(v)
+#endif
+
+#define SWIG_NewPointerObj(p,type,flags) caml_val_ptr(p,type)
+#define SWIG_GetModule(clientdata) SWIG_Ocaml_GetModule()
+#define SWIG_SetModule(clientdata, pointer) SWIG_Ocaml_SetModule(pointer)
+
+#define SWIG_contract_assert(expr, msg) if(!(expr)) {failwith(msg);} else
+
+    SWIGSTATIC int
+    SWIG_GetPtr(void *source, void **result, swig_type_info *type, swig_type_info *result_type);
+    
+    SWIGSTATIC void *
+    SWIG_MustGetPtr (CAML_VALUE v,  swig_type_info *type);
+    
+    SWIGSTATIC CAML_VALUE _wrap_delete_void( CAML_VALUE );
+    
+    SWIGSTATIC int enum_to_int( char *name, CAML_VALUE v );
+    SWIGSTATIC CAML_VALUE int_to_enum( char *name, int v );
+
+    SWIGSTATIC CAML_VALUE caml_list_nth( CAML_VALUE lst, int n );
+    SWIGSTATIC CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt );
+    SWIGSTATIC int caml_list_length( CAML_VALUE lst );
+    SWIGSTATIC CAML_VALUE caml_array_new( int n );
+    SWIGSTATIC void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item );
+    SWIGSTATIC CAML_VALUE caml_array_nth( CAML_VALUE arr, int n );
+    SWIGSTATIC int caml_array_length( CAML_VALUE arr );
+
+    SWIGSTATIC CAML_VALUE caml_val_char( char c );
+    SWIGSTATIC CAML_VALUE caml_val_uchar( unsigned char c );
+
+    SWIGSTATIC CAML_VALUE caml_val_short( short s );
+    SWIGSTATIC CAML_VALUE caml_val_ushort( unsigned short s );
+    
+    SWIGSTATIC CAML_VALUE caml_val_int( int x );
+    SWIGSTATIC CAML_VALUE caml_val_uint( unsigned int x );
+
+    SWIGSTATIC CAML_VALUE caml_val_long( long x );
+    SWIGSTATIC CAML_VALUE caml_val_ulong( unsigned long x );
+
+    SWIGSTATIC CAML_VALUE caml_val_float( float f );
+    SWIGSTATIC CAML_VALUE caml_val_double( double d );
+
+    SWIGSTATIC CAML_VALUE caml_val_ptr( void *p, swig_type_info *descriptor );
+
+    SWIGSTATIC CAML_VALUE caml_val_string( const char *str );
+    SWIGSTATIC CAML_VALUE caml_val_string_len( const char *str, int len );
+
+    SWIGSTATIC long caml_long_val( CAML_VALUE v );
+    SWIGSTATIC double caml_double_val( CAML_VALUE v );
+
+    SWIGSTATIC int caml_ptr_val_internal( CAML_VALUE v, void **out,
+				      swig_type_info *descriptor );
+    SWIGSTATIC void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor );
+
+    SWIGSTATIC char *caml_string_val( CAML_VALUE v );
+    SWIGSTATIC int caml_string_len( CAML_VALUE v );
+
+#ifdef __cplusplus
+}
+#endif
+
+/* mzschemedec.swg ends here */
+
+/* -*-c-*- */
+
+/* SWIG pointer structure */
+
+#include <string.h>
+#include <assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define C_bool 0
+#define C_char 1
+#define C_uchar 2
+#define C_short 3
+#define C_ushort 4
+#define C_int 5
+#define C_uint 6
+#define C_int32 7
+#define C_int64 8
+#define C_float 9
+#define C_double 10
+#define C_ptr 11
+#define C_array 12
+#define C_list 13
+#define C_obj 14
+#define C_string 15
+#define C_enum 16
+#define C_director_core 17
+
+
+/* Cast a pointer if possible; returns 1 if successful */
+    
+    SWIGSTATIC int
+    SWIG_Cast (void *source, swig_type_info *source_type,
+	       void **ptr, swig_type_info *dest_type)
+    {
+	if( !source ) { // Special case for NULL.  This is a popular question
+	    // for other modules on the list, so I want an easy way out...
+	    *ptr = 0;
+	    return 0;
+	}
+
+#ifdef TYPE_CAST_VERBOSE
+	fprintf( stderr, "Trying to cast %s to %s\n", 
+		 source_type ? source_type->str : "<none>",
+		 dest_type ? dest_type->str : "<none>" );
+#endif
+	if (dest_type != source_type) {
+	    /* We have a type mismatch.  Will have to look through our type
+	       mapping table to figure out whether or not we can accept this
+	       datatype. 
+	       --
+	       Ignore typechecks for void *.  Allow any conversion. */
+	    if( !dest_type || !source_type || 
+		!strcmp(dest_type->name,"_p_void") ||
+		!strcmp(source_type->name,"_p_void") ) {
+		*ptr = source;
+		return 0;
+	    } else {
+		swig_cast_info *tc = 
+		    SWIG_TypeCheckStruct(source_type, dest_type );
+#ifdef TYPE_CAST_VERBOSE
+		fprintf( stderr, "Typecheck -> %s\n",
+			 tc ? tc->str : "<none>" );
+#endif
+		if( tc ) {
+		    *ptr = SWIG_TypeCast( tc, source );
+		    return 0;
+		} else
+		    return -1;
+	    }
+	} else {
+	    *ptr = source;
+	    return 0;
+	}
+    }
+
+/* Return 0 if successful. */
+    SWIGSTATIC int
+    SWIG_GetPtr(void *inptr, void **outptr, 
+		swig_type_info *intype, swig_type_info *outtype) {
+	if (intype) {
+	    return SWIG_Cast(inptr, intype,
+			     outptr, outtype) == -1;
+	} else {
+	    *outptr = inptr;
+	    return 0;
+	}
+    }
+
+    SWIGSTATIC void caml_print_list( CAML_VALUE v );
+
+    SWIGSTATIC void caml_print_val( CAML_VALUE v ) {
+	switch( SWIG_Tag_val(v) ) {
+	case C_bool:
+	    if( Bool_val(SWIG_Field(v,0)) ) fprintf( stderr, "true " );
+	    else fprintf( stderr, "false " );
+	    break;
+	case C_char:
+	case C_uchar:
+	    fprintf( stderr, "'%c' (\\%03d) ", 
+		     (Int_val(SWIG_Field(v,0)) >= ' ' &&
+		      Int_val(SWIG_Field(v,0)) < 127) ? Int_val(SWIG_Field(v,0)) : '.',
+		     Int_val(SWIG_Field(v,0)) );
+	    break;
+	case C_short:
+	case C_ushort:
+	case C_int:
+	    fprintf( stderr, "%d ", (int)caml_long_val(v) );
+	    break;
+
+	case C_uint:
+	case C_int32:
+	    fprintf( stderr, "%ud ", (unsigned int)caml_long_val(v) );
+	    break;
+	case C_int64:
+	    fprintf( stderr, "%ld ", caml_long_val(v) );
+	    break;
+	case C_float:
+	case C_double:
+	    fprintf( stderr, "%f ", caml_double_val(v) );
+	    break;
+
+	case C_ptr:
+	{
+	    void *vout = 0;
+	    swig_type_info *ty = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1));
+	    caml_ptr_val_internal(v,&vout,0);
+	    fprintf( stderr, "PTR(%p,%s) ", 
+		     vout,
+		     ty ? ty->name : "(null)" );
+	}
+	break;
+	case C_array:
+	{
+	    unsigned int i;
+	    for( i = 0; i < Wosize_val( SWIG_Field(v,0) ); i++ ) 
+		caml_print_val( SWIG_Field(SWIG_Field(v,0),i) );
+	}
+	break;
+	case C_list:
+	    caml_print_list( SWIG_Field(v,0) );
+	    break;
+	case C_obj:
+	    fprintf( stderr, "OBJ(%p) ", (void *)SWIG_Field(v,0) );
+	    break;
+	case C_string:
+	{
+	    void *cout;
+	    caml_ptr_val_internal(v,&cout,0);
+	    fprintf( stderr, "'%s' ", (char *)cout );
+	} 
+	break;
+	}
+    }
+
+    SWIGSTATIC void caml_print_list( CAML_VALUE v ) {
+	CAMLparam1(v);
+	while( v && Is_block(v) ) {
+	    fprintf( stderr, "[ " );
+	    caml_print_val( SWIG_Field(v,0) );
+	    fprintf( stderr, "]\n" );
+	    v = SWIG_Field(v,1);
+	}
+	CAMLreturn0;
+    }
+
+    SWIGSTATIC CAML_VALUE caml_list_nth( CAML_VALUE lst, int n ) {
+	CAMLparam1(lst);
+	int i = 0;
+	while( i < n && lst && Is_block(lst) ) {
+	    i++; lst = SWIG_Field(lst,1);
+	}
+	if( lst == Val_unit ) CAMLreturn(Val_unit);
+	else CAMLreturn(SWIG_Field(lst,0));
+    }
+    
+    SWIGSTATIC CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt ) {
+	CAMLparam2(lst,elt);
+	SWIG_CAMLlocal3(v,vt,lh);
+	lh = Val_unit;
+	v = Val_unit;
+
+	/* Appending C_void should have no effect */
+	if( !Is_block(elt) ) return lst;
+
+	while( lst && Is_block(lst) ) {
+	    if( v && v != Val_unit ) {
+		vt = alloc_tuple(2);
+		SWIG_Store_field(v,1,vt);
+		v = vt;
+	    } else {
+		v = lh = alloc_tuple(2);
+	    }
+	    SWIG_Store_field(v,0,SWIG_Field(lst,0));
+	    lst = SWIG_Field(lst,1);
+	}
+
+	if( v && Is_block(v) ) {
+	    vt = alloc_tuple(2);
+	    SWIG_Store_field(v,1,vt);
+	    v = vt;
+	} else {
+	    v = lh = alloc_tuple(2);
+	}
+	SWIG_Store_field(v,0,elt);
+	SWIG_Store_field(v,1,Val_unit);
+
+	CAMLreturn(lh);
+    }
+
+    SWIGSTATIC int caml_list_length( CAML_VALUE lst ) {
+	CAMLparam1(lst);
+	int i = 0;
+	while( lst && Is_block(lst) ) { i++; lst = SWIG_Field(lst,1); }
+	CAMLreturn(i);
+    }
+
+    SWIGSTATIC void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item ) {
+	CAMLparam2(arr,item);
+	SWIG_Store_field(SWIG_Field(arr,0),n,item);
+	CAMLreturn0;
+    }
+
+    SWIGSTATIC value caml_array_nth( CAML_VALUE arr, int n ) {
+	CAMLparam1(arr);
+	if( SWIG_Tag_val(arr) == C_array )
+	    CAMLreturn(SWIG_Field(SWIG_Field(arr,0),n));
+	else if( SWIG_Tag_val(arr) == C_list )
+	    CAMLreturn(caml_list_nth(arr,0));
+	else
+	    failwith("Need array or list");
+    }
+
+    SWIGSTATIC int caml_array_len( CAML_VALUE arr ) {
+	CAMLparam1(arr);
+	if( SWIG_Tag_val(arr) == C_array )
+	    CAMLreturn(Wosize_val(SWIG_Field(arr,0)));
+	else if( SWIG_Tag_val(arr) == C_list )
+	    CAMLreturn(caml_list_length(arr));
+	else
+	    failwith("Need array or list");
+    }
+
+    SWIGSTATIC CAML_VALUE caml_swig_alloc(int x,int y) {
+	return caml_alloc(x,y);
+    }
+
+    SWIGSTATIC value caml_array_new( int n ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(vv);
+	vv = caml_swig_alloc(1,C_array);
+	SWIG_Store_field(vv,0,alloc_tuple(n));
+	CAMLreturn(vv);
+    }
+    
+    SWIGSTATIC CAML_VALUE caml_val_bool( int b ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(bv);
+	bv = caml_swig_alloc(1,C_bool);
+	SWIG_Store_field(bv,0,Val_bool(b));
+	CAMLreturn(bv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_char( char c ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(cv);
+	cv = caml_swig_alloc(1,C_char);
+	SWIG_Store_field(cv,0,Val_int(c));
+	CAMLreturn(cv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_uchar( unsigned char uc ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(ucv);
+	ucv = caml_swig_alloc(1,C_uchar);
+	SWIG_Store_field(ucv,0,Val_int(uc));
+	CAMLreturn(ucv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_short( short s ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(sv);
+	sv = caml_swig_alloc(1,C_short);
+	SWIG_Store_field(sv,0,Val_int(s));
+	CAMLreturn(sv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_ushort( unsigned short us ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(usv);
+	usv = caml_swig_alloc(1,C_ushort);
+	SWIG_Store_field(usv,0,Val_int(us));
+	CAMLreturn(usv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_int( int i ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(iv);
+	iv = caml_swig_alloc(1,C_int);
+	SWIG_Store_field(iv,0,Val_int(i));
+	CAMLreturn(iv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_uint( unsigned int ui ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(uiv);
+	uiv = caml_swig_alloc(1,C_int);
+	SWIG_Store_field(uiv,0,Val_int(ui));
+	CAMLreturn(uiv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_long( long l ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(lv);
+	lv = caml_swig_alloc(1,C_int64);
+	SWIG_Store_field(lv,0,copy_int64(l));
+	CAMLreturn(lv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_ulong( unsigned long ul ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(ulv);
+	ulv = caml_swig_alloc(1,C_int64);
+	SWIG_Store_field(ulv,0,copy_int64(ul));
+	CAMLreturn(ulv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_float( float f ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(fv);
+	fv = caml_swig_alloc(1,C_float);
+	SWIG_Store_field(fv,0,copy_double((double)f));
+	CAMLreturn(fv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_double( double d ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(fv);
+	fv = caml_swig_alloc(1,C_double);
+	SWIG_Store_field(fv,0,copy_double(d));
+	CAMLreturn(fv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_ptr( void *p, swig_type_info *info ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(vv);
+	vv = caml_swig_alloc(2,C_ptr);
+	SWIG_Store_field(vv,0,copy_int64((long)p));
+	SWIG_Store_field(vv,1,copy_int64((long)info));
+	CAMLreturn(vv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_string( const char *p ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(vv);
+	if( !p ) CAMLreturn(caml_val_ptr( (void *)p, 0 ));
+	vv = caml_swig_alloc(1,C_string);
+	SWIG_Store_field(vv,0,copy_string(p));
+	CAMLreturn(vv);
+    }
+
+    SWIGSTATIC CAML_VALUE caml_val_string_len( const char *p, int len ) {
+	CAMLparam0();
+	SWIG_CAMLlocal1(vv);
+	if( !p || len < 0 ) CAMLreturn(caml_val_ptr( (void *)p, 0 ));
+	vv = caml_swig_alloc(1,C_string);
+	SWIG_Store_field(vv,0,alloc_string(len));
+	memcpy(String_val(SWIG_Field(vv,0)),p,len);
+	CAMLreturn(vv);
+    }
+
+    #define caml_val_obj(v, name) caml_val_obj_helper(v, SWIG_TypeQuery((name)), name)
+    SWIGSTATIC CAML_VALUE caml_val_obj_helper( void *v, swig_type_info *type, char *name) {
+	CAMLparam0();
+	CAMLreturn(callback2(*caml_named_value("caml_create_object_fn"),
+			     caml_val_ptr(v,type),
+			     copy_string(name)));
+    }
+
+    SWIGSTATIC long caml_long_val_full( CAML_VALUE v, char *name ) {
+	CAMLparam1(v);
+	if( !Is_block(v) ) return 0;
+
+	switch( SWIG_Tag_val(v) ) {
+	case C_bool:
+	case C_char:
+	case C_uchar:
+	case C_short:
+	case C_ushort:
+	case C_int:
+	    CAMLreturn(Int_val(SWIG_Field(v,0)));
+	case C_uint:
+	case C_int32:
+	    CAMLreturn(Int32_val(SWIG_Field(v,0)));
+	case C_int64:
+	    CAMLreturn((long)SWIG_Int64_val(SWIG_Field(v,0)));
+	case C_float:
+	case C_double:
+	    CAMLreturn((long)Double_val(SWIG_Field(v,0)));
+	case C_string:
+	    CAMLreturn((long)String_val(SWIG_Field(v,0)));
+	case C_ptr:
+	    CAMLreturn((long)SWIG_Int64_val(SWIG_Field(SWIG_Field(v,0),0)));
+	case C_enum: {
+	    SWIG_CAMLlocal1(ret);
+	    CAML_VALUE *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int");
+	    if( !name ) failwith( "Not an enum conversion" );
+	    ret = callback2(*enum_to_int,*caml_named_value(name),v);
+	    CAMLreturn(caml_long_val(ret));
+	}
+	default:
+	    failwith("No conversion to int");
+	}
+    }
+
+    SWIGSTATIC long caml_long_val( CAML_VALUE v ) {
+	return caml_long_val_full(v,0);
+    }
+
+    SWIGSTATIC double caml_double_val( CAML_VALUE v ) {
+	CAMLparam1(v);
+	if( !Is_block(v) ) return 0.0;
+	switch( SWIG_Tag_val(v) ) {
+	case C_bool:
+	case C_char:
+	case C_uchar:
+	case C_short:
+	case C_ushort:
+	case C_int:
+	    CAMLreturn(Int_val(SWIG_Field(v,0)));
+	case C_uint:
+	case C_int32:
+	    CAMLreturn(Int32_val(SWIG_Field(v,0)));
+	case C_int64:
+	    CAMLreturn(SWIG_Int64_val(SWIG_Field(v,0)));
+	case C_float:
+	case C_double:
+	    CAMLreturn(Double_val(SWIG_Field(v,0)));
+	default:
+	    fprintf( stderr, "Unknown block tag %d\n", SWIG_Tag_val(v) );
+	    failwith("No conversion to double");
+	}
+    }
+
+    SWIGSTATIC int caml_ptr_val_internal( CAML_VALUE v, void **out, 
+					  swig_type_info *descriptor ) {
+	CAMLparam1(v);
+	void *outptr = NULL;
+        swig_type_info *outdescr = NULL;
+
+	if( v == Val_unit ) {
+	    *out = 0;
+	    CAMLreturn(0);
+	}
+	if( !Is_block(v) ) return -1;
+	switch( SWIG_Tag_val(v) ) {
+	case C_int:
+	    if( !caml_long_val( v ) ) {
+		*out = 0;
+		CAMLreturn(0);
+	    } else {
+		*out = 0;
+		CAMLreturn(1);
+	    }
+	    break;
+	case C_obj:
+	    CAMLreturn
+		(caml_ptr_val_internal
+		 (callback(*caml_named_value("caml_obj_ptr"),v),
+		  out,descriptor));
+	case C_string:
+	    outptr = (void *)String_val(SWIG_Field(v,0));
+	    break;
+	case C_ptr:
+	    outptr = (void *)(long)SWIG_Int64_val(SWIG_Field(v,0));
+            outdescr = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1));
+	    break;
+	default:
+	    *out = 0;
+	    CAMLreturn(1);
+	    break;
+	}
+	
+	CAMLreturn(SWIG_GetPtr(outptr,out,outdescr,descriptor));
+    }
+
+    SWIGSTATIC void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor ) {
+	CAMLparam0();
+#ifdef TYPE_CAST_VERBOSE
+	caml_print_val( v );
+#endif
+	void *out = NULL;
+	if( !caml_ptr_val_internal( v, &out, descriptor ) )
+	    CAMLreturn(out);
+	else
+	    failwith( "No appropriate conversion found." );
+    }
+
+    SWIGSTATIC char *caml_string_val( CAML_VALUE v ) {
+	return (char *)caml_ptr_val( v, 0 );
+    }
+
+    SWIGSTATIC int caml_string_len( CAML_VALUE v ) {
+	switch( SWIG_Tag_val(v) ) {
+	case C_string:
+	    return string_length(SWIG_Field(v,0));
+	default:
+	    return strlen((char *)caml_ptr_val(v,0));
+	}
+    }
+
+    SWIGSTATIC int caml_bool_check( CAML_VALUE v ) {
+	CAMLparam1(v);
+	
+	if( !Is_block(v) ) return 0;
+	
+	switch( SWIG_Tag_val(v) ) {
+	case C_bool:
+	case C_ptr:
+	case C_string:
+	    CAMLreturn(1);
+	default:
+	    CAMLreturn(0);
+	}
+    }
+
+    SWIGSTATIC int caml_int_check( CAML_VALUE v ) {
+	CAMLparam1(v);
+	
+	if( !Is_block(v) ) return 0;
+	
+	switch( SWIG_Tag_val(v) ) {
+	case C_char:
+	case C_uchar:
+	case C_short:
+	case C_ushort:
+	case C_int:
+	case C_uint:
+	case C_int32:
+	case C_int64:
+	    CAMLreturn(1);
+
+	default:
+	    CAMLreturn(0);
+	}
+    }
+
+    SWIGSTATIC int caml_float_check( CAML_VALUE v ) {
+	CAMLparam1(v);
+	if( !Is_block(v) ) return 0;
+
+	switch( SWIG_Tag_val(v) ) {
+	case C_float:
+	case C_double:
+	    CAMLreturn(1);
+
+	default:
+	    CAMLreturn(0);
+	}	
+    }
+
+    SWIGSTATIC int caml_ptr_check( CAML_VALUE v ) {
+	CAMLparam1(v);
+	if( !Is_block(v) ) return 0;
+
+	switch( SWIG_Tag_val(v) ) {
+	case C_string:
+	case C_ptr:
+	case C_int64:
+	    CAMLreturn(1);
+
+	default:
+	    CAMLreturn(0);
+	}	
+    }
+
+    static swig_module_info *SWIG_Ocaml_GetModule() {
+      CAML_VALUE pointer;
+
+      pointer = callback(*caml_named_value("swig_find_type_info"), caml_val_int(0));
+      if (Is_block(pointer) && SWIG_Tag_val(pointer) == C_ptr) {
+        return (swig_module_info *)(void *)(long)SWIG_Int64_val(SWIG_Field(pointer,0));
+      }
+      return 0;
+    }
+
+    static void SWIG_Ocaml_SetModule(swig_module_info *pointer) {
+      CAML_VALUE mod_pointer;
+
+      mod_pointer = caml_val_ptr(pointer, NULL);
+      callback(*caml_named_value("swig_set_type_info"), mod_pointer);
+    }
+
+#ifdef __cplusplus
+}
+#endif
+#undef value
+
+/* ocaml keywords */
+/* There's no need to use this, because of my rewriting machinery.  C++
+ * words never collide with ocaml keywords */
+//%include "ocamlkw.swg"
+
+
+/* -------- TYPES TABLE (BEGIN) -------- */
+
+#define SWIGTYPE_p_magic_set swig_types[0]
+#define SWIGTYPE_p_void swig_types[1]
+static swig_type_info *swig_types[2];
+static swig_module_info swig_module = {swig_types, 2, 0, 0, 0, 0};
+#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
+#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
+
+/* -------- TYPES TABLE (END) -------- */
+
+
+#define  SWIG_MemoryError    1
+#define  SWIG_IOError        2
+#define  SWIG_RuntimeError   3
+#define  SWIG_IndexError     4
+#define  SWIG_TypeError      5
+#define  SWIG_DivisionByZero 6
+#define  SWIG_OverflowError  7
+#define  SWIG_SyntaxError    8
+#define  SWIG_ValueError     9
+#define  SWIG_SystemError   10
+#define  SWIG_UnknownError  99
+
+
+#define OCAML_MSG_BUF_LEN 1024
+SWIGINTERN void SWIG_exception_(int code, const char *msg) {
+  char msg_buf[OCAML_MSG_BUF_LEN];
+  sprintf( msg_buf, "Exception(%d): %s\n", code, msg );
+  failwith( msg_buf );  
+}
+#define SWIG_exception(a,b) SWIG_exception_((a),(b))
+
+
+/* Includes the header in the wrapper code */
+#include "/usr/include/magic.h"
+
+static int _swig_wrap_MAGIC_NONE = 0x000;
+static int _swig_wrap_MAGIC_DEBUG = 0x001;
+static int _swig_wrap_MAGIC_SYMLINK = 0x002;
+static int _swig_wrap_MAGIC_COMPRESS = 0x004;
+static int _swig_wrap_MAGIC_DEVICES = 0x008;
+static int _swig_wrap_MAGIC_MIME = 0x010;
+static int _swig_wrap_MAGIC_CONTINUE = 0x020;
+static int _swig_wrap_MAGIC_CHECK = 0x040;
+static int _swig_wrap_MAGIC_PRESERVE_ATIME = 0x080;
+static int _swig_wrap_MAGIC_RAW = 0x100;
+static int _swig_wrap_MAGIC_ERROR = 0x200;
+SWIGEXT CAML_VALUE _wrap_MAGIC_NONE(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_NONE);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_DEBUG(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_DEBUG);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_SYMLINK(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_SYMLINK);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_COMPRESS(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_COMPRESS);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_DEVICES(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_DEVICES);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_MIME(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_MIME);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_CONTINUE(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_CONTINUE);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_CHECK(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_CHECK);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_PRESERVE_ATIME(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_PRESERVE_ATIME);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_RAW(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_RAW);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_MAGIC_ERROR(CAML_VALUE args) {
+    CAML_VALUE swig_result;
+    
+    {
+        swig_result = caml_val_int(_swig_wrap_MAGIC_ERROR);
+    }
+    
+    return swig_result;
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_openmagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    int arg1 ;
+    magic_t result;
+    
+    swig_result = Val_unit;
+    {
+        arg1 = caml_long_val(caml_list_nth(args,0));
+    }
+    result = (magic_t)magic_open(arg1);
+    
+    {
+        /* %typemap(directorin) SWIGTYPE *, SWIGTYPE (CLASS::*) */
+        CAML_VALUE *fromval = caml_named_value("create_struct magic_set_from_ptr");
+        if( fromval ) {
+            rv = callback(*fromval,caml_val_ptr((void *)result,SWIGTYPE_p_magic_set));
+        } else {
+            rv = caml_val_ptr ((void *)result,SWIGTYPE_p_magic_set);
+        }
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_closemagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    magic_close(arg1);
+    
+    rv = Val_unit;
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_filemagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    char *arg2 = (char *) 0 ;
+    char *result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    {
+        /* %typemap(in) char * ... */
+        arg2 = (char *)caml_string_val(caml_list_nth(args,1));
+    }
+    result = (char *)magic_file(arg1,(char const *)arg2);
+    
+    {
+        rv = caml_val_string((char *)result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_buffermagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    void *arg2 = (void *) 0 ;
+    size_t arg3 ;
+    char *result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    {
+        arg2 = caml_ptr_val(caml_list_nth(args,1),SWIGTYPE_p_void);
+    }
+    {
+        arg3 = caml_long_val(caml_list_nth(args,2));
+    }
+    result = (char *)magic_buffer(arg1,(void const *)arg2,arg3);
+    
+    {
+        rv = caml_val_string((char *)result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_errormagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    char *result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    result = (char *)magic_error(arg1);
+    
+    {
+        rv = caml_val_string((char *)result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_setflagsmagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    int arg2 ;
+    int result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    {
+        arg2 = caml_long_val(caml_list_nth(args,1));
+    }
+    result = (int)magic_setflags(arg1,arg2);
+    
+    {
+        rv = caml_val_int(result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_loadmagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    char *arg2 = (char *) 0 ;
+    int result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    {
+        /* %typemap(in) char * ... */
+        arg2 = (char *)caml_string_val(caml_list_nth(args,1));
+    }
+    result = (int)magic_load(arg1,(char const *)arg2);
+    
+    {
+        rv = caml_val_int(result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_compilemagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    char *arg2 = (char *) 0 ;
+    int result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    {
+        /* %typemap(in) char * ... */
+        arg2 = (char *)caml_string_val(caml_list_nth(args,1));
+    }
+    result = (int)magic_compile(arg1,(char const *)arg2);
+    
+    {
+        rv = caml_val_int(result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_checkmagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    char *arg2 = (char *) 0 ;
+    int result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    {
+        /* %typemap(in) char * ... */
+        arg2 = (char *)caml_string_val(caml_list_nth(args,1));
+    }
+    result = (int)magic_check(arg1,(char const *)arg2);
+    
+    {
+        rv = caml_val_int(result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+SWIGEXT CAML_VALUE _wrap_magic_errnomagiclib (CAML_VALUE args)
+{
+    CAMLparam1(args);
+    SWIG_CAMLlocal2(swig_result,rv);
+    int _v = 0;
+    magic_t arg1 = (magic_t) 0 ;
+    int result;
+    
+    swig_result = Val_unit;
+    {
+        /* %typemap(in) SWIGTYPE * */
+        arg1 = (magic_t)caml_ptr_val(caml_list_nth(args,0),SWIGTYPE_p_magic_set);
+    }
+    result = (int)magic_errno(arg1);
+    
+    {
+        rv = caml_val_int(result);
+    }
+    swig_result = caml_list_append(swig_result,rv);
+    CAMLreturn(swig_result);
+}
+
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
+
+static swig_type_info _swigt__p_magic_set = {"_p_magic_set", "struct magic_set *|magic_t", 0, 0, 0};
+static swig_type_info _swigt__p_void = {"_p_void", "void *", 0, 0, 0};
+
+static swig_type_info *swig_type_initial[] = {
+  &_swigt__p_magic_set,
+  &_swigt__p_void,
+};
+
+static swig_cast_info _swigc__p_magic_set[] = {  {&_swigt__p_magic_set, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_void[] = {  {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}};
+
+static swig_cast_info *swig_cast_initial[] = {
+  _swigc__p_magic_set,
+  _swigc__p_void,
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
+
+#define SWIG_init f_magiclib_init
+/*************************************************************************
+ * Type initialization:
+ * This problem is tough by the requirement that no dynamic 
+ * memory is used. Also, since swig_type_info structures store pointers to 
+ * swig_cast_info structures and swig_cast_info structures store pointers back
+ * to swig_type_info structures, we need some lookup code at initialization. 
+ * The idea is that swig generates all the structures that are needed. 
+ * The runtime then collects these partially filled structures. 
+ * The SWIG_InitializeModule function takes these initial arrays out of 
+ * swig_module, and does all the lookup, filling in the swig_module.types
+ * array with the correct data and linking the correct swig_cast_info
+ * structures together.
+
+ * The generated swig_type_info structures are assigned staticly to an initial 
+ * array. We just loop though that array, and handle each type individually.
+ * First we lookup if this type has been already loaded, and if so, use the
+ * loaded structure instead of the generated one. Then we have to fill in the
+ * cast linked list. The cast data is initially stored in something like a
+ * two-dimensional array. Each row corresponds to a type (there are the same
+ * number of rows as there are in the swig_type_initial array). Each entry in
+ * a column is one of the swig_cast_info structures for that type.
+ * The cast_initial array is actually an array of arrays, because each row has
+ * a variable number of columns. So to actually build the cast linked list,
+ * we find the array of casts associated with the type, and loop through it 
+ * adding the casts to the list. The one last trick we need to do is making
+ * sure the type pointer in the swig_cast_info struct is correct.
+
+ * First off, we lookup the cast->type name to see if it is already loaded. 
+ * There are three cases to handle:
+ *  1) If the cast->type has already been loaded AND the type we are adding
+ *     casting info to has not been loaded (it is in this module), THEN we
+ *     replace the cast->type pointer with the type pointer that has already
+ *     been loaded.
+ *  2) If BOTH types (the one we are adding casting info to, and the 
+ *     cast->type) are loaded, THEN the cast info has already been loaded by
+ *     the previous module so we just ignore it.
+ *  3) Finally, if cast->type has not already been loaded, then we add that
+ *     swig_cast_info to the linked list (because the cast->type) pointer will
+ *     be correct.
+**/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+    SWIGRUNTIME void
+    SWIG_InitializeModule(void *clientdata) {
+        swig_type_info *type, *ret;
+        swig_cast_info *cast;
+        size_t i;
+        swig_module_info *module_head;
+        static int init_run = 0;
+        
+        clientdata = clientdata;
+        
+        if (init_run) return;
+        init_run = 1;
+        
+        /* Initialize the swig_module */
+        swig_module.type_initial = swig_type_initial;
+        swig_module.cast_initial = swig_cast_initial;
+        
+        /* Try and load any already created modules */
+        module_head = SWIG_GetModule(clientdata);
+        if (module_head) {
+            swig_module.next = module_head->next;
+            module_head->next = &swig_module;
+        } else {
+            /* This is the first module loaded */
+            swig_module.next = &swig_module;
+            SWIG_SetModule(clientdata, &swig_module);
+        }
+        
+        /* Now work on filling in swig_module.types */
+        for (i = 0; i < swig_module.size; ++i) {
+            type = 0;
+            
+            /* if there is another module already loaded */
+            if (swig_module.next != &swig_module) {
+                type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
+            }
+            if (type) {
+                /* Overwrite clientdata field */
+                if (swig_module.type_initial[i]->clientdata) type->clientdata = swig_module.type_initial[i]->clientdata;
+            } else {
+                type = swig_module.type_initial[i];
+            }
+            
+            /* Insert casting types */
+            cast = swig_module.cast_initial[i];
+            while (cast->type) {
+                /* Don't need to add information already in the list */
+                ret = 0;
+                if (swig_module.next != &swig_module) {
+                    ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
+                }
+                if (ret && type == swig_module.type_initial[i]) {
+                    cast->type = ret;
+                    ret = 0;
+                }
+                
+                if (!ret) {
+                    if (type->cast) {
+                        type->cast->prev = cast;
+                        cast->next = type->cast;
+                    }
+                    type->cast = cast;
+                }
+                
+                cast++;
+            }
+            
+            /* Set entry in modules->types array equal to the type */
+            swig_module.types[i] = type;
+        }
+    }
+    
+    /* This function will propagate the clientdata field of type to
+    * any new swig_type_info structures that have been added into the list
+    * of equivalent types.  It is like calling
+    * SWIG_TypeClientData(type, clientdata) a second time.
+    */
+    SWIGRUNTIME void
+    SWIG_PropagateClientData(void) {
+        size_t i;
+        swig_cast_info *equiv;
+        static int init_run = 0;
+        
+        if (init_run) return;
+        init_run = 1;
+        
+        for (i = 0; i < swig_module.size; i++) {
+            if (swig_module.types[i]->clientdata) {
+                equiv = swig_module.types[i]->cast;
+                while (equiv) {
+                    if (!equiv->converter) {
+                        if (equiv->type && !equiv->type->clientdata)
+                        SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
+                    }
+                    equiv = equiv->next;
+                }
+            }
+        }
+    }
+    
+#ifdef __cplusplus
+}
+#endif
+
+SWIGEXT void SWIG_init() {
+    SWIG_InitializeModule(0);
+    
+}
+
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/magic_magic.ml ./src/utils/lib/magic_magic.ml
--- ./src/utils/lib/magic_magic.ml	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/magic_magic.ml	2006-03-16 23:02:31.000000000 +0100
@@ -0,0 +1,38 @@
+(* Copyright 2006 *)
+(*
+    This file is part of mldonkey.
+
+    mldonkey 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.
+
+    mldonkey 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 mldonkey; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*)
+
+open Swig
+open Magiclib
+open Printf2
+
+module type MagicInfo =
+sig
+  val magic_fileinfo : string -> string
+end
+
+module MagicInfo : MagicInfo = struct
+
+  let magic_fileinfo file =
+    let magiccookie = _magic_open (C_int 0) in (* just opens the lib *)
+    ignore (_magic_load (C_list [magiccookie; (C_int 0)])); (* returns 0 on ok *)
+    let fileinfo = _magic_file (C_list [magiccookie; (C_string file)]) in
+    ignore (_magic_close magiccookie); (* close the lib *)
+    Swig.get_string fileinfo
+
+end
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/magic.ml.in ./src/utils/lib/magic.ml.in
--- ./src/utils/lib/magic.ml.in	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/magic.ml.in	2006-03-16 23:09:17.000000000 +0100
@@ -0,0 +1,27 @@
+(* Copyright 2006 *)
+(*
+    This file is part of mldonkey.
+
+    mldonkey 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.
+
+    mldonkey 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 mldonkey; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*)
+
+open Printf2
+
+module type MagicInfo =
+sig
+  val magic_fileinfo : string -> string
+end
+
+module M : MagicInfo = @MAGICLIB@.MagicInfo
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/magic_nomagic.ml ./src/utils/lib/magic_nomagic.ml
--- ./src/utils/lib/magic_nomagic.ml	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/magic_nomagic.ml	2006-03-16 23:07:01.000000000 +0100
@@ -0,0 +1,31 @@
+(* Copyright 2006 *)
+(*
+    This file is part of mldonkey.
+
+    mldonkey 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.
+
+    mldonkey 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 mldonkey; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*)
+
+open Printf2
+
+module type MagicInfo =
+sig
+  val magic_fileinfo : string -> string
+end
+
+module MagicInfo : MagicInfo = struct
+
+  let magic_fileinfo file = "not implemented"
+
+end
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/swig.ml ./src/utils/lib/swig.ml
--- ./src/utils/lib/swig.ml	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/swig.ml	2006-03-15 22:15:17.000000000 +0100
@@ -0,0 +1,160 @@
+(* -*- tuareg -*- *)
+open Int32
+open Int64
+
+type enum = [ `Int of int ]
+
+type 'a c_obj_t = 
+    C_void
+  | C_bool of bool
+  | C_char of char
+  | C_uchar of char
+  | C_short of int
+  | C_ushort of int
+  | C_int of int
+  | C_uint of int32
+  | C_int32 of int32
+  | C_int64 of int64
+  | C_float of float
+  | C_double of float
+  | C_ptr of int64 * int64
+  | C_array of 'a c_obj_t array
+  | C_list of 'a c_obj_t list
+  | C_obj of (string -> 'a c_obj_t -> 'a c_obj_t)
+  | C_string of string
+  | C_enum of 'a
+  | C_director_core of 'a c_obj_t * 'a c_obj_t option ref
+
+type c_obj = enum c_obj_t
+
+exception BadArgs of string
+exception BadMethodName of string * string
+exception NotObject of c_obj
+exception NotEnumType of c_obj
+exception LabelNotFromThisEnum of c_obj
+exception InvalidDirectorCall of c_obj
+exception NoSuchClass of string
+let rec invoke obj = 
+  match obj with 
+      C_obj o -> o 
+    | C_director_core (o,r) -> invoke o
+    | _ -> raise (NotObject (Obj.magic obj))
+let _ = Callback.register "swig_runmethod" invoke
+
+let fnhelper arg =
+  match arg with C_list l -> l | C_void -> [] | _ -> [ arg ]
+
+let rec get_int x = 
+  match x with
+      C_bool b -> if b then 1 else 0
+    | C_char c
+    | C_uchar c -> (int_of_char c)
+    | C_short s
+    | C_ushort s
+    | C_int s -> s
+    | C_uint u
+    | C_int32 u -> (Int32.to_int u)
+    | C_int64 u -> (Int64.to_int u)
+    | C_float f -> (int_of_float f)
+    | C_double d -> (int_of_float d)
+    | C_ptr (p,q) -> (Int64.to_int p)
+    | C_obj o -> (try (get_int (o "int" C_void))
+		  with _ -> (get_int (o "&" C_void)))
+    | _ -> raise (Failure "Can't convert to int")
+
+let rec get_float x = 
+  match x with
+      C_char c
+    | C_uchar c -> (float_of_int (int_of_char c))
+    | C_short s -> (float_of_int s)
+    | C_ushort s -> (float_of_int s)
+    | C_int s -> (float_of_int s)
+    | C_uint u
+    | C_int32 u -> (float_of_int (Int32.to_int u))
+    | C_int64 u -> (float_of_int (Int64.to_int u))
+    | C_float f -> f
+    | C_double d -> d
+    | C_obj o -> (try (get_float (o "float" C_void))
+		  with _ -> (get_float (o "double" C_void)))
+    | _ -> raise (Failure "Can't convert to float")
+
+let rec get_char x =
+  (char_of_int (get_int x))
+
+let rec get_string x = 
+  match x with 
+      C_string str -> str
+    | _ -> raise (Failure "Can't convert to string")
+
+let rec get_bool x = 
+  match x with
+      C_bool b -> b
+    | _ -> 
+	(try if get_int x != 0 then true else false
+	 with _ -> raise (Failure "Can't convert to bool"))
+
+let disown_object obj = 
+  match obj with
+      C_director_core (o,r) -> r := None
+    | _ -> raise (Failure "Not a director core object")
+let _ = Callback.register "caml_obj_disown" disown_object
+let addr_of obj = 
+  match obj with
+      C_obj _ -> (invoke obj) "&" C_void
+    | C_director_core (self,r) -> (invoke self) "&" C_void
+    | C_ptr _ -> obj
+    | _ -> raise (Failure "Not a pointer.")
+let _ = Callback.register "caml_obj_ptr" addr_of
+
+let make_float f = C_float f
+let make_double f = C_double f
+let make_string s = C_string s
+let make_bool b = C_bool b
+let make_char c = C_char c
+let make_char_i c = C_char (char_of_int c)
+let make_uchar c = C_uchar c
+let make_uchar_i c = C_uchar (char_of_int c)
+let make_short i = C_short i
+let make_ushort i = C_ushort i
+let make_int i = C_int i
+let make_uint i = C_uint (Int32.of_int i)
+let make_int32 i = C_int32 (Int32.of_int i)
+let make_int64 i = C_int64 (Int64.of_int i)
+
+let new_derived_object cfun x_class args =
+  begin
+    let get_object ob =
+      match !ob with
+          None ->
+    raise (NotObject C_void)
+        | Some o -> o in
+    let ob_ref = ref None in
+    let class_fun class_f ob_r =
+      (fun meth args -> class_f (get_object ob_r) meth args) in
+    let new_class = class_fun x_class ob_ref in
+    let dircore = C_director_core (C_obj new_class,ob_ref) in
+    let obj =
+    cfun (match args with
+            C_list argl -> (C_list ((dircore :: argl)))
+	  | C_void -> (C_list [ dircore ])
+          | a -> (C_list [ dircore ; a ])) in
+    ob_ref := Some obj ;
+      obj
+  end
+  
+let swig_current_type_info = ref C_void
+let find_type_info obj = !swig_current_type_info 
+let _ = Callback.register "swig_find_type_info" find_type_info
+let set_type_info obj =
+  match obj with
+    C_ptr _ -> swig_current_type_info := obj ;
+               obj
+    | _ -> raise (Failure "Internal error: passed non pointer to set_type_info")
+let _ = Callback.register "swig_set_type_info" set_type_info
+
+let class_master_list = Hashtbl.create 20
+let register_class_byname nm co = 
+  Hashtbl.replace class_master_list nm (Obj.magic co)
+let create_class nm arg = 
+  try (Obj.magic (Hashtbl.find class_master_list nm)) arg with _ -> raise (NoSuchClass nm)
+
diff -a -x CVS -x Root -x Repository -x Tag -x Entries -x Entries.Log -x .svn -x '*.rej' -x '*.orig' -x .cvsignore -N -r -u ./src/utils/lib/swig.mli ./src/utils/lib/swig.mli
--- ./src/utils/lib/swig.mli	1970-01-01 01:00:00.000000000 +0100
+++ ./src/utils/lib/swig.mli	2006-03-15 22:15:17.000000000 +0100
@@ -0,0 +1,62 @@
+(* -*- tuareg -*- *)
+
+type enum = [ `Int of int ]
+
+type 'a c_obj_t = 
+    C_void
+  | C_bool of bool
+  | C_char of char
+  | C_uchar of char
+  | C_short of int
+  | C_ushort of int
+  | C_int of int
+  | C_uint of int32
+  | C_int32 of int32
+  | C_int64 of int64
+  | C_float of float
+  | C_double of float
+  | C_ptr of int64 * int64
+  | C_array of 'a c_obj_t array
+  | C_list of 'a c_obj_t list
+  | C_obj of (string -> 'a c_obj_t -> 'a c_obj_t)
+  | C_string of string
+  | C_enum of 'a
+  | C_director_core of 'a c_obj_t * 'a c_obj_t option ref
+
+type c_obj = enum c_obj_t
+
+exception InvalidDirectorCall of c_obj
+exception NoSuchClass of string
+
+val invoke : ('a c_obj_t) -> (string -> 'a c_obj_t -> 'a c_obj_t)
+val fnhelper : 'a c_obj_t -> 'a c_obj_t list
+
+val get_int : 'a c_obj_t -> int
+val get_float : 'a c_obj_t -> float
+val get_string : 'a c_obj_t -> string
+val get_char : 'a c_obj_t -> char
+val get_bool : 'a c_obj_t -> bool
+
+val make_float : float -> 'a c_obj_t
+val make_double : float -> 'a c_obj_t
+val make_string : string -> 'a c_obj_t
+val make_bool : bool -> 'a c_obj_t
+val make_char : char -> 'a c_obj_t
+val make_char_i : int -> 'a c_obj_t
+val make_uchar : char -> 'a c_obj_t
+val make_uchar_i : int -> 'a c_obj_t
+val make_short : int -> 'a c_obj_t
+val make_ushort : int -> 'a c_obj_t
+val make_int : int -> 'a c_obj_t
+val make_uint : int -> 'a c_obj_t
+val make_int32 : int -> 'a c_obj_t
+val make_int64 : int -> 'a c_obj_t
+
+val new_derived_object: 
+  ('a c_obj_t -> 'a c_obj_t) ->
+  ('a c_obj_t -> string -> 'a c_obj_t -> 'a c_obj_t) ->
+  'a c_obj_t -> 'a c_obj_t
+  
+val register_class_byname : string -> ('a c_obj_t -> 'a c_obj_t) -> unit
+val create_class : string -> 'a c_obj_t -> 'a c_obj_t
+
