Index: trunk.xml/src/settings/evermore
===================================================================
--- trunk.xml/src/settings/evermore	(Revision 2554)
+++ trunk.xml/src/settings/evermore	(Arbeitskopie)
@@ -67,6 +67,9 @@
 # we want mysql 
 enable_use_mysql=yes
 
+# we want xml2
+enable_use_xml=xml2
+
 # but we do not want old names for efuns
 enable_use_deprecated=no
 
Index: trunk.xml/src/settings/unitopia
===================================================================
--- trunk.xml/src/settings/unitopia	(Revision 2554)
+++ trunk.xml/src/settings/unitopia	(Arbeitskopie)
@@ -62,7 +62,7 @@
 enable_use_parse_command=no
 enable_use_mysql=no
 enable_use_sqlite=yes
-enable_use_iksemel=yes
+enable_use_xml=yes
 enable_use_deprecated=no
 enable_use_pcre=no
 enable_lpc_array_calls=yes
Index: trunk.xml/src/arraylist.c
===================================================================
--- trunk.xml/src/arraylist.c	(Revision 0)
+++ trunk.xml/src/arraylist.c	(Revision 0)
@@ -0,0 +1,155 @@
+/*---------------------------------------------------------------------------
+ * Arraylist utility functions.
+ *
+ *---------------------------------------------------------------------------
+ * These functions help to assemble an array whose length is unknown at the
+ * beginning. So at first all elements are kept in a singly linked list
+ * until finalize_arraylist is called.
+ *
+ * The linked list is saved as an error handler in a svalue_t, so it will
+ * destruct itself and all of its elements automatically when the svalue_t
+ * is freed.
+ *
+ * This structure is not designed to survive a garbage_collection.
+ * It should always be finalized or freed in the same execution thread.
+ *---------------------------------------------------------------------------
+ */
+
+#include "driver.h"
+#include "typedefs.h"
+
+#include "array.h"
+#include "arraylist.h"
+#include "interpret.h"
+#include "simulate.h"
+#include "svalue.h"
+#include "xalloc.h"
+
+/*-------------------------------------------------------------------------*/
+/* Types */
+
+typedef struct arraylist_s arraylist_t;
+typedef struct arraylist_element_s arraylist_element_t;
+
+struct arraylist_s
+{
+    svalue_t head; /* The error handler. */
+
+    arraylist_element_t *first;
+    arraylist_element_t *last;
+    int num;
+};
+
+struct arraylist_element_s
+{
+    svalue_t value;
+    arraylist_element_t * next;
+};
+
+/*-------------------------------------------------------------------------*/
+static void
+cleanup_arraylist (svalue_t * list)
+
+/* Our cleanup handler, called when the arraylist is freed.
+ */
+{
+    arraylist_t * data = (arraylist_t *) list;
+    arraylist_element_t * element = data->first;
+
+    while (element)
+    {
+        arraylist_element_t * temp = element;
+
+        element = element->next;
+
+        free_svalue(&(temp->value));
+        xfree(temp);
+    }
+
+    xfree(data);
+}
+
+/*-------------------------------------------------------------------------*/
+void
+put_arraylist (svalue_t * list)
+
+/* Create an arraylist and put it into <list>.
+ */
+{
+    arraylist_t * data;
+
+    memsafe(data = xalloc(sizeof(*data)), sizeof(*data), "arraylist");
+
+    data->head.type = T_ERROR_HANDLER;
+    data->head.u.error_handler = cleanup_arraylist;
+    data->num = 0;
+    data->first = NULL;
+    data->last = NULL;
+
+    list->type = T_LVALUE;
+    list->u.lvalue = &(data->head);
+} /* put_arraylist() */
+
+/*-------------------------------------------------------------------------*/
+svalue_t *
+enhance_arraylist (svalue_t * list)
+
+/* Add an element to the arraylist to <list>.
+ * It is the responsibility of the caller to ensure
+ * that <list> is in fact an arraylist.
+ */
+{
+    arraylist_t * data = (arraylist_t *) list->u.lvalue;
+    arraylist_element_t * element;
+
+    memsafe(element = xalloc(sizeof(*element)), sizeof(*element), "arraylist element");
+    element->next = NULL;
+    put_number(&(element->value), 0);
+
+    if (data->last == NULL)
+    {
+        data->first = element;
+        data->last = element;
+    }
+    else
+    {
+        data->last->next = element;
+        data->last = element;
+    }
+    data->num++;
+
+    return &(element->value);
+
+} /* enhance_arraylist() */
+
+/*-------------------------------------------------------------------------*/
+void
+finalize_arraylist (svalue_t * list)
+
+/* Turn the arraylist in <list> into a proper array.
+ */
+{
+    arraylist_t * data = (arraylist_t *) list->u.lvalue;
+    arraylist_element_t * element;
+    vector_t * result;
+    svalue_t * item;
+
+    result = allocate_array(data->num);
+
+    element = data->first;
+    item = result->item;
+
+    while (element)
+    {
+        arraylist_element_t * temp = element;
+
+        *item = element->value;
+
+        item++;
+        element = element->next;
+        xfree(temp);
+    }
+
+    xfree(data);
+    put_array(list, result);
+} /* finalize_arraylist() */
Index: trunk.xml/src/arraylist.h
===================================================================
--- trunk.xml/src/arraylist.h	(Revision 0)
+++ trunk.xml/src/arraylist.h	(Revision 0)
@@ -0,0 +1,14 @@
+#ifndef ARRAYLIST_H__
+#define ARRAYLIST_H__ 1
+
+#include "driver.h"
+#include <stddef.h>
+
+#include "typedefs.h"
+#include "svalue.h"
+
+extern void put_arraylist(svalue_t * list);
+extern svalue_t * enhance_arraylist(svalue_t * list);
+extern void finalize_arraylist(svalue_t * list);
+
+#endif /* ARRAYLIST_H__ */
Index: trunk.xml/src/main.c
===================================================================
--- trunk.xml/src/main.c	(Revision 2554)
+++ trunk.xml/src/main.c	(Arbeitskopie)
@@ -77,8 +77,16 @@
 #include "pkg-mysql.h"
 #endif
 
-#ifdef USE_IKSEMEL
-#include "pkg-iksemel.h"
+#ifdef USE_XML
+#    if defined(HAS_XML2) && defined(HAS_IKSEMEL)
+#        error Both, libxml2 and iksemel enabled.
+#    endif
+#    ifdef HAS_XML2
+#        include "pkg-xml2.h"
+#    endif
+#    ifdef HAS_IKSEMEL
+#        include "pkg-iksemel.h"
+#    endif
 #endif
 
 #ifdef USE_GCRYPT
@@ -469,10 +477,16 @@
         }
 #endif
 
-#ifdef USE_IKSEMEL
+#ifdef USE_XML
+#ifdef HAS_IKSEMEL
         pkg_iksemel_init();
 #endif
 
+#ifdef HAS_XML2
+        pkg_xml2_init();
+#endif
+#endif
+
         /* If the master_name hasn't been set, select a sensible default */
         if ('\0' == master_name[0])
         {
@@ -1852,8 +1866,16 @@
 #ifdef HAS_IDN
                               , "idna supported\n"
 #endif
-#ifdef USE_IKSEMEL
-                              , "iksemel supported\n"
+#ifdef USE_XML
+                              , "XML supported ("
+#  if defined(HAS_XML2)
+                                "libxml2"
+#  elif defined(HAS_IKSEMEL)
+                                "iksemel"
+#  else
+                                "<unknown>"
+#  endif
+                                ")\n"
 #endif
 #ifdef USE_IPV6
                               , "IPv6 supported\n"
Index: trunk.xml/src/lex.c
===================================================================
--- trunk.xml/src/lex.c	(Revision 2554)
+++ trunk.xml/src/lex.c	(Arbeitskopie)
@@ -849,7 +849,7 @@
 #ifdef USE_SQLITE
     add_permanent_define("__SQLITE__", -1, string_copy("1"), MY_FALSE);
 #endif
-#ifdef USE_IKSEMEL
+#ifdef USE_XML
     add_permanent_define("__XML_DOM__", -1, string_copy("1"), MY_FALSE);
 #endif
 #ifdef USE_ALISTS
Index: trunk.xml/src/pkg-iksemel.c
===================================================================
--- trunk.xml/src/pkg-iksemel.c	(Revision 2554)
+++ trunk.xml/src/pkg-iksemel.c	(Arbeitskopie)
@@ -10,8 +10,9 @@
  *------------------------------------------------------------------
  */
 #include "driver.h"
+#include "machine.h"
 
-#ifdef USE_IKSEMEL
+#if defined(USE_XML) && defined(HAS_IKSEMEL)
 
 #include <iksemel.h>
 #include "array.h"
@@ -557,4 +558,4 @@
     return sp;
 }
  
-#endif /* USE_IKSEMEL */
+#endif /* USE_XML && HAS_IKSEMEL */
Index: trunk.xml/src/pkg-iksemel.h
===================================================================
--- trunk.xml/src/pkg-iksemel.h	(Revision 2554)
+++ trunk.xml/src/pkg-iksemel.h	(Arbeitskopie)
@@ -2,18 +2,15 @@
 #define PKG_IKSEMEL_H__ 1
 
 #include "driver.h"
+#include "machine.h"
 
-#ifdef USE_IKSEMEL
+#if defined(USE_XML) && defined(HAS_IKSEMEL)
 
-#ifndef HAS_IKSEMEL
-#error "pkg-iksemel configured even though the machine doesn't support iksemel."
-#endif
-
 /* --- Prototypes --- */
 
 void pkg_iksemel_init();
 
-#endif /* USE_IKSEMEL */
+#endif /* USE_XML && HAS_IKSEMEL */
 
 #endif /* PKG_IKSEMEL_H__ */
 
Index: trunk.xml/src/autoconf/configure.in
===================================================================
--- trunk.xml/src/autoconf/configure.in	(Revision 2554)
+++ trunk.xml/src/autoconf/configure.in	(Arbeitskopie)
@@ -87,6 +87,83 @@
     not_available="[$not_available], $1"
 fi])
 
+dnl Search for library $2.
+dnl First try using pkg-config, put its results into $1_LIBS and $1_CFLAGS.
+dnl Then try searching in /usr/include, /usr/include/$4 and ${$5}.
+dnl Try to compile $6.
+dnl Look for library $7.
+dnl If successful set $3 to yes, otherwise to no.
+AC_DEFUN([AC_MY_SEARCH_LIB],
+[
+    saveflags="$CFLAGS"
+    saveeflags="$EXTRA_CFLAGS"
+
+    ifdef([PKG_CHECK_MODULES],[
+        PKG_CHECK_MODULES([$1],[$2],[$3]=yes,[$3]=no)
+    ],[
+         [$3]=no
+    ])
+
+    # No pkg-config, search manually.
+    if test $[$3] = no; then
+        AC_MSG_CHECKING(for [$4] support)
+        for TESTPATH in "" "${[$5]}" "${[$5]}/include" "${[$5]}/include/[$4]" "/usr/include/[$4]" "/usr/local/include" "/usr/local/include/[$4]" ; do
+            if test "x$TESTPATH" != "x"; then
+                CFLAGS="$saveflags -I$TESTPATH"
+            else
+                CFLAGS="$saveflags"
+            fi
+            AC_TRY_COMPILE([$6],,
+                [$3]=yes
+                if test "x$TESTPATH" != "x"; then
+                    EXTRA_CFLAGS="-I$TESTPATH $EXTRA_CFLAGS"
+                fi
+                break;
+                ,
+                CFLAGS="$saveflags"
+            )
+        done
+        AC_MSG_RESULT($[$3])
+    elif test "x$[$1]_CFLAGS" != "x"; then
+        EXTRA_CFLAGS="$[$1]_CFLAGS $EXTRA_CFLAGS"
+    fi
+
+    if test $[$3] = yes; then
+        if test "x$[$1]_LIBS" != "x"; then
+            PKGLIBS="$PKGLIBS $[$1]_LIBS"
+        else
+            tmp=""
+
+            for TESTPATH in "" "${[$5]}" "${[$5]}/lib" "${[$5]}/lib/[$4]" "/usr/lib/[$4]" "/usr/local/lib" "/usr/local/lib/[$4]" ; do
+                if test "x$TESTPATH" != "x"; then
+                    CFLAGS="$saveflags -L$TESTPATH"
+                else
+                    CFLAGS="$saveflags"
+                fi
+
+                AC_CHECK_LIB([$7],xmlParseFile,
+                    if test "x$TESTPATH" != "x"; then
+                        tmp="$PKGLIBS -L$TESTPATH -l[$7]"
+                    else
+                        tmp="$PKGLIBS -l[$7]"
+                    fi
+                    break
+                )
+            done
+
+            if test "x$tmp" == "x"; then
+                [$3]=no
+
+                EXTRA_CFLAGS="$saveeflags"
+            else
+                PKGLIBS="$tmp"
+            fi
+        fi
+
+        CFLAGS="$saveflags"
+    fi
+])
+
 dnl
 dnl let's start
 AC_INIT(prolang.y)
@@ -120,7 +197,8 @@
 AC_MY_ARG_ENABLE(use-pgsql,no,,[Enables PostgreSQL support])
 AC_MY_ARG_ENABLE(use-sqlite,no,,[Enables SQLite support])
 AC_MY_ARG_ENABLE(use-pcre,yes,,[Enables PCRE: no/yes/builtin/no-builtin])
-AC_MY_ARG_ENABLE(use-iksemel,no,,[Enables use of iksemel for XML parsing])
+AC_MY_ARG_ENABLE(use-xml,no,,[Enables XML support: no/xml2/iksemel/yes])
+AC_MY_ARG_WITH(xml-path,,,[Optional location of the XML include/ and lib/ directory])
 AC_MY_ARG_ENABLE(use-deprecated,yes,,[Enables obsolete and deprecated efuns])
 AC_MY_ARG_ENABLE(use-structs,yes,,[Enables structs])
 AC_MY_ARG_ENABLE(use-tls,no,,[Enables Transport Layer Security over Telnet: no/gnu/ssl/yes])
@@ -324,19 +402,25 @@
   enable_use_sqlite="yes"
 fi
 
-AC_UPDATE_VAR(enable_use_iksemel)
-if test "x$enable_use_iksemel" = "x" || test "x$enable_use_iksemel" = "xyes"; then
-  cdef_use_iksemel="#define"
-  iksemel_path=
-  enable_use_iksemel="yes"
-elif test "x$enable_use_iksemel" = "xno"; then
-  cdef_use_iksemel="#undef"
-  iksemel_path=
+AC_UPDATE_VAR(enable_use_xml)
+if test "x$enable_use_xml" = "x" || test "x$enable_use_xml" = "xyes"; then
+  cdef_use_xml="#define"
+  xml_package="any"
+  enable_use_xml="yes"
+elif test "x$enable_use_xml" = "xno"; then
+  cdef_use_xml="#undef"
+  xml_package="any"
 else
-  cdef_use_iksemel="#define"
-  iksemel_path="$enable_use_iksemel"
-  enable_use_iksemel="yes"
+  cdef_use_xml="#define"
+  xml_package="$enable_use_xml"
+  enable_use_xml="yes"
 fi
+AC_UPDATE_VAR(with_xml_path)
+if test "x$with_xml_path" = "x" -o "x$with_xml_path" = "xno" ; then
+  xml_path=""
+else
+  xml_path="$with_xml_path"
+fi
 
 AC_UPDATE_VAR(enable_use_tls)
 if test "x$enable_use_tls" = "x" || test "x$enable_use_tls" = "xyes"; then
@@ -385,7 +469,6 @@
 AC_CDEF_FROM_ENABLE(use_ipv6)
 AC_CDEF_FROM_ENABLE(use_deprecated)
 AC_CDEF_FROM_ENABLE(use_structs)
-AC_CDEF_FROM_ENABLE(use_tls)
 AC_CDEF_FROM_ENABLE(use_new_inlines)
 AC_CDEF_FROM_ENABLE(use_set_light)
 AC_CDEF_FROM_ENABLE(use_set_is_wizard)
@@ -1567,189 +1650,107 @@
 
 # --- SQLite3 ---
 
-# Note: Some compilers don't have /usr/local/include in their standard
-# searchpath.
+ifdef([PKG_PROG_PKG_CONFIG],[PKG_PROG_PKG_CONFIG()],[])
 
-AC_CACHE_CHECK(for SQLite3,lp_cv_has_sqlite3,
-for TESTPATH in "" "$sqlite_path" "$sqlite_path/include" "/usr/local/include" ; do
-    saveflags="$CFLAGS"
-    if test "x$TESTPATH" != "x"; then
-        CFLAGS="$saveflags -I$TESTPATH"
-    fi
-AC_TRY_COMPILE([
-#include <sqlite3.h>
+AC_MY_SEARCH_LIB(SQLITE3,sqlite3,lp_cv_has_sqlite3,sqlite3,xml_path,
+[
+    #include <sqlite3.h>
 
-sqlite3 * foo(void)
-{
+    sqlite3 * foo(void)
+    {
+        return (sqlite3*)0;
+    }
+],sqlite3)
 
-    return (sqlite3*)0;
-}
-],,
-lp_cv_has_sqlite3=yes
-if test "x$TESTPATH" != "x"; then
-    EXTRA_CFLAGS="-I$TESTPATH $EXTRA_CFLAGS"
-fi
-break;
-,
-lp_cv_has_sqlite3=no
-CFLAGS="$saveflags"
-)
-done
-)
 
-# The system has the include files - now search for the libraries.
 if test $lp_cv_has_sqlite3 = yes; then
-  saveflags="$CFLAGS"
-  AC_DEFINE(HAS_SQLITE3, 1, [Does the machine offer SQLite3?])
+    AC_DEFINE(HAS_SQLITE3, 1, [Does the machine offer SQLite3?])
 
-  if test $enable_use_sqlite = yes; then
-    tmp=""
+    if test "x$enable_use_sqlite" = "xyes"; then
+        savelibs="$LIBS"
+        LIBS="$LIBS $PKGLIBS"
 
-    AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -lsqlite3")
+        # Check if it uses pthreads
 
-    if test "x$sqlite_path" == "x"; then
-        unset ac_cv_lib_sqlite3_main
-        if test -d "${sqlite_path}/lib/sqlite"; then
-            CFLAGS="$saveflags -L${sqlite_path}/lib/sqlite"
-            AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L${sqlite_path}/lib/sqlite -lsqlite3")
-        elif test -d "${sqlite_path}/lib"; then
-            CFLAGS="$saveflags -L${sqlite_path}/lib"
-            AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L${sqlite_path}/lib -lsqlite3")
-        elif test -d "${sqlite_patch}"; then
-            CFLAGS="$saveflags -L$sqlite_path"
-            AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L$sqlite_path -lsqlite3")
+        AC_SEARCH_LIBS(pthread_create,,
+            lp_cv_sqlite3_uses_pthreads=yes,
+            lp_cv_sqlite3_uses_pthreads=no
+        )
+
+        if test $lp_cv_sqlite3_uses_pthreads = yes ; then
+             AC_DEFINE(SQLITE3_USES_PTHREADS, 1, [Does SQLite3 use pthreads?])
         fi
-    fi
 
-    if test "x$tmp" == "x"; then
-        unset ac_cv_lib_sqlite3_main
-        if test -d "/usr/local/lib"; then
-            CFLAGS="$saveflags -L/usr/local/lib"
-            AC_CHECK_LIB(sqlite3,main, tmp="$PKGLIBS -L/usr/local/lib -lsqlite3")
-        fi
+        LIBS="$savelibs"
     fi
-
-    if test "x$tmp" == "x"; then
+else
+    if test $enable_use_sqlite = yes; then
         echo "libsqlite3 library not found - disabling SQLite support"
         AC_NOT_AVAILABLE(use-sqlite)
-        cdef_use_sqlite="#undef"
-        enable_use_sqlite="no"
-        sqlite=
-        lp_cv_has_sqlite="no"
-    else
-        PKGLIBS="$tmp"
     fi
-  fi
 
-  if test "x$enable_use_sqlite" = "xyes"; then
-      savelibs="$LIBS"
-      LIBS="$LIBS $PKGLIBS"
-      
-      # Check if it uses pthreads
+    cdef_use_sqlite="#undef"
+    enable_use_sqlite="no"
+    sqlite=
+fi
 
-      AC_CHECK_LIB(sqlite3, pthread_create,
-      	   lp_cv_sqlite3_uses_pthreads=yes,
-      	   lp_cv_sqlite3_uses_pthreads=no
-      )
+# --- XML ---
 
-      if test $lp_cv_sqlite3_uses_pthreads = yes ; then
-           AC_DEFINE(SQLITE3_USES_PTHREADS, 1, [Does SQLite3 use pthreads?])
-      fi
+has_xml=no
 
-      LIBS="$savelibs"
-  fi
+if test "$xml_package" = "any" -o "$xml_package" = "xml2"; then
 
-  CFLAGS="$saveflags"
-else
-  if test $enable_use_sqlite = yes; then
-      AC_NOT_AVAILABLE(use-sqlite)
-      cdef_use_sqlite="#undef"
-      enable_use_sqlite=no
-  fi
-fi
+    AC_MY_SEARCH_LIB(XML2,libxml-2.0,lp_cv_has_xml2,libxml2,xml_path,
+    [
+        #include <libxml/parser.h>
 
-# --- Iksemel ---
+        void foo(void)
+        {
+            xmlElementType type = XML_ELEMENT_NODE;
+        }
+    ],xml2)
 
-AC_CACHE_CHECK(for Iksemel,lp_cv_has_iksemel,
-for TESTPATH in "" "$iksemel_path" "$iksemel_path/include" "/usr/local/include" ; do
-    saveflags="$CFLAGS"
-    if test "x$TESTPATH" != "x"; then
-        CFLAGS="$saveflags -I$TESTPATH"
+    if test $lp_cv_has_xml2 = yes; then
+        if test "$enable_use_xml" = "yes"; then
+            has_xml=yes
+            xml_package=xml2
+            AC_DEFINE(HAS_XML2, 1, [Does the machine have libxml2?])
+        fi
     fi
-AC_TRY_COMPILE([
-#include <iksemel.h>
-
-iks * foo(void)
-{
-
-    return (iks*)0;
-}
-],,
-lp_cv_has_iksemel=yes
-if test "x$TESTPATH" != "x"; then
-    EXTRA_CFLAGS="-I$TESTPATH $EXTRA_CFLAGS"
 fi
-break;
-,
-lp_cv_has_iksemel=no
-CFLAGS="$saveflags"
-)
-done
-)
 
-# The system has the include files - now search for the libraries.
-if test $lp_cv_has_iksemel = yes; then
-  saveflags="$CFLAGS"
-  AC_DEFINE(HAS_IKSEMEL, 1, [Does the machine offer iksemel?])
+if test "$xml_package" = "any" -o "$xml_package" = "iksemel"; then
 
-  if test $enable_use_iksemel = yes; then
-    tmp=""
+    AC_MY_SEARCH_LIB(IKSEMEL,iksemel,lp_cv_has_iksemel,iksemel,xml_path,
+    [
+        #include <iksemel.h>
 
-    AC_CHECK_LIB(iksemel,main, tmp="$PKGLIBS -liksemel")
+        iks * foo(void)
+        {
+            return (iks*)0;
+        }
+    ],iksemel)
 
-    if test "x$iksemel_path" == "x"; then
-        unset ac_cv_lib_iksemel_main
-        if test -d "${iksemel_path}/lib/iksemel"; then
-            CFLAGS="$saveflags -L${iksemel_path}/lib/iksemel"
-            AC_CHECK_LIB(iksemel,main, tmp="$PKGLIBS -L${iksemel_path}/lib/iksemel -liksemel")
-        elif test -d "${iksemel_path}/lib"; then
-            CFLAGS="$saveflags -L${iksemel_path}/lib"
-            AC_CHECK_LIB(iksemel,main, tmp="$PKGLIBS -L${iksemel_path}/lib -liksemel")
-        elif test -d "${iksemel_patch}"; then
-            CFLAGS="$saveflags -L$iksemel_path"
-            AC_CHECK_LIB(iksemel,main, tmp="$PKGLIBS -L$iksemel_path -liksemel")
+    if test $lp_cv_has_iksemel = yes; then
+        if test "$enable_use_xml" = "yes"; then
+            has_xml=yes
+            xml_package=iksemel
+            AC_DEFINE(HAS_IKSEMEL, 1, [Does the machine have Iksemel?])
         fi
     fi
+fi
 
-    if test "x$tmp" == "x"; then
-        unset ac_cv_lib_iksemel_main
-        if test -d "/usr/local/lib"; then
-            CFLAGS="$saveflags -L/usr/local/lib"
-            AC_CHECK_LIB(iksemel,main, tmp="$PKGLIBS -L/usr/local/lib -liksemel")
-        fi
+if test "$has_xml" = no; then
+    if test $enable_use_xml = yes; then
+        echo "XML not supported - disabling XML support."
+        AC_NOT_AVAILABLE(use-xml)
     fi
 
-    if test "x$tmp" == "x"; then
-        echo "libiksemel library not found - disabling Iksemel support"
-        AC_NOT_AVAILABLE(use-iksemel)
-        cdef_use_iksemel="#undef"
-        enable_use_iksemel="no"
-        iksemel=
-        lp_cv_has_iksemel="no"
-    else
-        PKGLIBS="$tmp"
-    fi
-  fi
-
-  CFLAGS="$saveflags"
-else
-  if test $enable_use_iksemel = yes; then
-      AC_NOT_AVAILABLE(use-iksemel)
-      cdef_use_iksemel="#undef"
-      enable_use_iksemel=no
-  fi
+    cdef_use_xml="#undef"
+    enable_use_xml=no
 fi
 
+
 # --- Check if we need zlib libraries for mccp ---
 
 if test "x$enable_use_mccp" = "x" || test "x$enable_use_mccp" = "xyes"; then
@@ -2323,7 +2324,7 @@
     # above correct program, we still can't use it. So check for that.
     if echo `eval $tcomp2` | egrep '[a-z]' >/dev/null; then
       :
-      # Success means 'we got output' here :-(
+      # Success means 'we got output' here  :-(
     else
         CFLAGS="$CFLAGS $TESTFLAG"
     fi
@@ -2729,7 +2730,7 @@
 AC_SUBST(cdef_use_mysql)
 AC_SUBST(cdef_use_pgsql)
 AC_SUBST(cdef_use_sqlite)
-AC_SUBST(cdef_use_iksemel)
+AC_SUBST(cdef_use_xml)
 AC_SUBST(cdef_use_alists)
 AC_SUBST(cdef_use_mccp)
 AC_SUBST(cdef_use_pcre)
Index: trunk.xml/src/pkg-xml2.c
===================================================================
--- trunk.xml/src/pkg-xml2.c	(Revision 0)
+++ trunk.xml/src/pkg-xml2.c	(Revision 0)
@@ -0,0 +1,572 @@
+/*------------------------------------------------------------------
+ * xml_* Efuns
+ *
+ *------------------------------------------------------------------
+ * This file holds the efuns interfacing with libxml2 and provides 
+ * functions for handling xml files and converting them between 
+ * mappings and xml data strings.
+ *
+ *   efun: xml_
+ *------------------------------------------------------------------
+ */
+#include "driver.h"
+#include "machine.h"
+
+#if defined(USE_XML) && defined(HAS_XML2)
+
+#include <libxml/parser.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xmlreader.h>
+#include "array.h"
+#include "arraylist.h"
+#include "xalloc.h"
+#include "mapping.h"
+#include "mstrings.h"
+#include "simulate.h"
+#include "interpret.h"
+#include "pkg-xml2.h"
+#include "typedefs.h"
+
+#include "../mudlib/sys/xml.h"
+
+/* Structure to walk over the attribute (properties in libxml2 jargon) to 
+ * create property-nodes
+ */
+typedef struct attribute_walk_extra_s attribute_walk_extra_t;
+
+/* Used to walk all attributes as well as for error handling. In case an 
+ * error happens, this structure is called too.
+ */
+struct attribute_walk_extra_s
+{
+    xmlTextWriterPtr writer;
+    char *tag_name;
+};
+
+/* Used for error handling. In case of an error our handler called with a 
+ * pointer ot this structure.
+ */
+struct xml_cleanup_s
+{
+    svalue_t head; /* push_error_handler saves the link to our handler here. */
+
+    xmlTextReaderPtr reader;
+    xmlTextWriterPtr writer;
+    xmlBufferPtr buf;
+};
+
+static void *
+xml_pkg_malloc (size_t size)
+
+/*
+ * Realize malloc with the driver-internal xalloc rather than a direct malloc()
+ */
+{
+    return xalloc(size);
+}
+
+static void
+xml_pkg_free (void * ptr)
+
+/*
+ * Realize free with the driver-internal xfree rather than a direct free()
+ */
+{
+    xfree(ptr);
+}
+
+static void *
+xml_pkg_realloc (void * ptr, size_t size)
+
+/*
+ * Realize realloc() with the driver-internal rexalloc_traced() including file
+ * and line rather the direct realloc()
+ */
+{
+    return rexalloc(ptr, size);
+}
+
+static char *
+xml_pkg_strdup (const char * str)
+
+/*
+ * Realize strdup with the driver interal string_copy instead of the direct
+ * strdup()
+ */
+{
+    return string_copy(str);
+}
+
+static void
+add_string_to_mapping (mapping_t *map, const char *skey, const char *svalue)
+
+/*
+ * Adds a string value under the given key to the given mapping. In case the 
+ * value already exists, it is overriden.
+ */
+{
+    svalue_t key;
+    svalue_t *value;
+
+    /* change the c string into an string_t */
+    put_c_string(&key, skey);
+
+    /* get or insert key */
+    value = get_map_lvalue(map, &key);
+
+    /* free the string_t again */
+    free_svalue(&key);
+
+    /* free maybe existing value (should not happen, i hope) */
+    free_svalue(value);
+
+    /* change the value of the key to the given value */
+    put_c_string(value, svalue);
+}
+
+static void
+parse_node (svalue_t *result, xmlTextReaderPtr reader)
+
+/*
+ * Parses the xml document beginning at <node> and returns the information 
+ * on the stack in <result>.
+ */
+{
+    vector_t *element = NULL;
+    svalue_t *children = NULL;
+    /* We have a tag here, so allocate a tag array with three elements 
+     * (name, contents and attributes)
+     */
+    memsafe(element = allocate_array(XML_TAG_SIZE), sizeof(*element)
+           , "new tag array");
+
+    /* Put the array as result */
+    put_array(result, element);
+
+    /* add name to array */
+    put_c_string(&element->item[XML_TAG_NAME]
+                , (const char *) xmlTextReaderConstName(reader));
+
+
+    if (xmlTextReaderHasAttributes(reader))
+    {
+        mapping_t *attributes = NULL;
+
+        /* allocate new mapping */
+        memsafe(attributes = allocate_mapping(xmlTextReaderAttributeCount(reader), 1)
+                , sizeof(*attributes), "new attributes mapping");
+
+        /* add the attributes to the array */
+        put_mapping(&element->item[XML_TAG_ATTRIBUTES], attributes);
+
+        while (MY_TRUE)
+        {
+            int ret;
+
+            ret = xmlTextReaderMoveToNextAttribute(reader);
+            if (ret == 0)
+                break;
+            else if (ret < 0)
+                errorf("(xml_parse) Error reading XML node.\n");
+
+            add_string_to_mapping(attributes
+                                 , (const char *) xmlTextReaderConstName(reader)
+                                 , (const char *) xmlTextReaderConstValue(reader));
+        }
+
+        xmlTextReaderMoveToElement(reader);
+    }
+
+    if (!xmlTextReaderIsEmptyElement(reader))
+        while (MY_TRUE)
+        {
+            int ret;
+            int is_node = 0;
+
+            ret = xmlTextReaderRead(reader);
+            if (ret == 0)
+                errorf("Bad arg 1 to xml_parse(): Premature end of data.\n");
+            else if(ret < 0)
+                errorf("(xml_parse) Error reading XML node.\n");
+
+            switch (xmlTextReaderNodeType(reader))
+            {
+            case XML_READER_TYPE_END_ELEMENT:
+                if (children != NULL)
+                    finalize_arraylist(children);
+                return;
+
+            case XML_READER_TYPE_ELEMENT:
+                is_node = 1;
+                /* FALLTHROUGH */
+            case XML_READER_TYPE_TEXT:
+            case XML_READER_TYPE_CDATA:
+                if (children == NULL)
+                {
+                    children = &(element->item[XML_TAG_CONTENTS]);
+                    put_arraylist(children);
+                }
+
+                if (is_node)
+                    parse_node(enhance_arraylist(children), reader);
+                else
+                    put_c_string(enhance_arraylist(children)
+                                , (const char *) xmlTextReaderConstValue(reader));
+
+                break;
+            }
+        }
+}
+
+static void
+walk_attribute_mapping(svalue_t *key, svalue_t *val, void *pextra)
+
+/*
+ * Callback for walk_mapping() used in generate_xml_node to add
+ * property-nodes to the node given in the <pextra>.
+ */
+{
+    attribute_walk_extra_t *extra = pextra;
+    int rc;
+
+    if (key->type != T_STRING)
+        errorf("Bad argument 1 to xml_generate(): expected string \
+                for attribute key of tag '%s'.\n", extra->tag_name);
+
+    if (val->type != T_STRING)
+        errorf("Bad argument 1 to xml_generate(): expected string for \
+                value of attribute '%s' of tag '%s'.\n"
+              , get_txt(key->u.str), extra->tag_name);
+
+    rc = xmlTextWriterWriteAttribute( extra->writer
+                                    , (xmlChar *) get_txt(key->u.str)
+                                    , (xmlChar *) get_txt(val->u.str));
+    if (rc < 0)
+         errorf("(xml_generate) Error writing attribute.\n");
+}
+
+static void
+xml_cleanup (svalue_t * arg)
+
+/*
+ * Takes care, that the xml document is correctly freed in case of an error 
+ * and at the end of the f_generate_xml(). Additionally the xml-parser 
+ * is cleaned up
+ */
+{
+    struct xml_cleanup_s * data;
+
+    data = (struct xml_cleanup_s *) arg;
+
+    if (data->buf)
+    {
+        xmlBufferFree(data->buf);
+    }
+
+    if (data->writer)
+    {
+       xmlFreeTextWriter(data->writer);
+    }
+
+    if (data->reader)
+    {
+       xmlFreeTextReader(data->reader);
+    }
+
+    xmlCleanupParser();
+
+    xfree(data);
+} /* xml_cleanup() */
+
+static void
+write_xml_node(vector_t * vnode, xmlTextWriterPtr writer)
+
+/* Writes a new xml node from the given array structure with the three
+ * elements (name, contents, attributes) using <writer>.
+ * The contents element may contain other tags, so recursion may occur.
+ */
+{
+    svalue_t *element;
+    char *name;
+    int rc;
+
+    if ((mp_int) VEC_SIZE(vnode) != 3)
+    {
+        errorf("Bad arg 1 to xml_generate(): tag is not an array with 3 \
+                elements.\n");
+
+        /* NOTREACHED */
+        return;
+    }
+
+    /* get the name, as this is essential */
+    element = &vnode->item[XML_TAG_NAME];
+
+    if (element->type != T_STRING)
+    {
+        errorf("Bad arg 1 to xml_generate(): first element of tag array \
+                not a string.\n");
+
+        /* NOTREACHED */
+        return;
+    }
+
+    name = get_txt(element->u.str);
+    rc = xmlTextWriterStartElement(writer, (xmlChar *) name);
+    if (rc < 0)
+        errorf("(xml_generate) Error writing XML element.\n");
+
+    /* now handle the attributes of this one */
+    element = &vnode->item[XML_TAG_ATTRIBUTES];
+
+    /* this might be absent */
+    if (element->type == T_MAPPING)
+    {
+        attribute_walk_extra_t extra;
+
+        extra.writer = writer;
+        extra.tag_name = name;
+
+        /* walk the mapping and add all attributes */
+        walk_mapping(element->u.map, &walk_attribute_mapping, &extra);
+    }
+    else if (element->type != T_NUMBER || element->u.number != 0)
+    {
+        errorf("Bad arg 1 to xml_generate(): second element of tag array not "
+               "NULL/mapping.\n");
+
+        /* NOTREACHED */
+        return;
+    }
+
+    /* now check, if the node has a contents */
+    element = &vnode->item[XML_TAG_CONTENTS];
+
+    /* this might even be absent */
+    if (element->type == T_POINTER)
+    {
+        int size;
+        int i;
+        vector_t *contents;
+
+        /* get the vector */
+        contents = element->u.vec;
+
+        /* get its size */
+        size = (mp_int)VEC_SIZE(contents);
+
+        for (i = 0; i < size; i++)
+        {
+            element = &contents->item[i];
+
+            if (element->type == T_STRING)
+            {
+                /* found content */
+                rc = xmlTextWriterWriteString(writer, (xmlChar *) get_txt(element->u.str));
+                if (rc < 0)
+                    errorf("(xml_generate) Error writing plain text.\n");
+            }
+            else if (element->type == T_POINTER)
+            {
+                /* found a sub tag */
+                write_xml_node(element->u.vec, writer);
+            }
+        }
+    }
+    else if (element->type != T_NUMBER || element->u.number != 0)
+    {
+        errorf("Bad arg 1 to xml_generate(): third element of tag array not "
+               "NULL/array.\n");
+
+        /* NOTREACHED */
+    }
+
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0)
+        errorf("(xml_generate) Error finishing XML element.\n");
+}
+
+void
+pkg_xml2_init ()
+{
+    /* Check for correct libxml version. */
+    LIBXML_TEST_VERSION
+
+    xmlMemSetup(xml_pkg_free, xml_pkg_malloc, xml_pkg_realloc, xml_pkg_strdup);
+}
+
+/*=========================================================================*/
+
+/*                           EFUNS                                         */
+
+/*-------------------------------------------------------------------------*/
+
+svalue_t *
+f_xml_generate (svalue_t *sp)
+
+/* EFUN xml_generate()
+ *
+ *     string xml_generate(mixed *xml)
+ *
+ * Converts the given <xml> array into an XML conform string, if
+ * possible. The <xml> argument array must have the same structure
+ * as xml_parse returns.
+ *
+ * In case the parameter does not follow these rules, errors are raised.
+ * The method returns a valid XML string otherwise.
+ */
+{
+    struct xml_cleanup_s * rec_data;
+    int rc;
+
+    memsafe(rec_data = xalloc(sizeof(*rec_data)), sizeof(*rec_data)
+            , "xml cleanup structure");
+    rec_data->buf = NULL;
+    rec_data->writer = NULL;
+    rec_data->reader = NULL;
+    push_error_handler(xml_cleanup, &(rec_data->head));
+
+    /* the output buffer. */
+    rec_data->buf = xmlBufferCreate();
+    if (rec_data->buf == NULL)
+        errorf("(xml_generate) Out of memory: temporary buffer.\n");
+
+    rec_data->writer = xmlNewTextWriterMemory(rec_data->buf, 0);
+    if (rec_data->writer == NULL)
+        errorf("(xml_generate) Out of memory: XML writer.\n");
+
+    rc = xmlTextWriterStartDocument(rec_data->writer, NULL, NULL, NULL);
+    if (rc < 0)
+        errorf("(xml_generate) Error starting XML document.\n");
+
+    write_xml_node(sp->u.vec, rec_data->writer);
+
+    rc = xmlTextWriterEndDocument(rec_data->writer);
+    if (rc < 0)
+        errorf("(xml_generate) Error finishing XML document.\n");
+
+    /* Free the array. */
+    free_svalue(sp);
+
+    put_c_string(sp, (char *) rec_data->buf->content);
+
+    /* The error handler will free the buffer
+     * and XML writer.
+     */
+    pop_stack();
+
+    return sp;
+}
+
+static void
+xml_pkg_error_handler(void * userData, xmlErrorPtr error)
+{
+    if (error)
+    {
+        errorf("Bad arg 1 to xml_parse(): %s", error->message);
+    }
+}
+
+svalue_t *
+f_xml_parse(svalue_t * sp)
+
+/* EFUN xml_parse()
+ *
+ *     mixed * xml_parse(string xml_text)
+ *
+ * Parses the given string <xml> as a XML conform string. The string must
+ * have only one root tag, subsequent root tags are ignored.
+ *
+ * If the xml string is correct, an array is of three elements is
+ * returned, where as the following indices are defined:
+ *
+ *     string XML_TAG_NAME
+ *         The name of the XML tag.
+ *
+ *     mixed * XML_TAG_CONTENTS
+ *         The contents of this xml tag as array. This array may
+ *         contain either strings, or arrags of sub-tags again with
+ *         three elements (see example)
+ *
+ *         If the xml tag does not contain anything, the element is
+ *         set 0.
+ *
+ *     mapping XML_TAG_ATTRIBUTES
+ *         All attributes given to the XML tag as mapping where the key
+ *         is the attribute name and the value is its string value.
+ *
+ *         If the xml tag does not contain any attributes, this element
+ *         is set 0.
+ *
+ * If the XML string is not well formed, or there is not enough memory to
+ * parse the whole XML structure into the array an error is raised. In case
+ * the XML string can't be parsed, cause it is not valid XML, 0 is returned.
+ */
+{
+    struct xml_cleanup_s * rec_data;
+
+    memsafe(rec_data = xalloc(sizeof(*rec_data)), sizeof(*rec_data)
+            , "xml cleanup structure");
+    rec_data->buf = NULL;
+    rec_data->writer = NULL;
+    rec_data->reader = NULL;
+    push_error_handler(xml_cleanup, &(rec_data->head));
+
+    /* Disable standard error functions, as they will print out errors
+     * to stderr automatically. We do not want that.
+     */
+    xmlSetGenericErrorFunc(NULL, NULL);
+    xmlSetStructuredErrorFunc(NULL, xml_pkg_error_handler);
+
+    rec_data->reader = xmlReaderForMemory(get_txt(sp->u.str)
+                                         , mstrsize(sp->u.str)
+                                         , NULL, NULL, XML_PARSE_NOENT);
+
+    if (rec_data->reader == NULL)
+        errorf("(xml_generate) Out of memory: XML reader.\n");
+
+    /* Put the result on top of the stack. */
+    push_number(inter_sp, 0);
+
+    /* Look for the first element. */
+    do
+    {
+        int ret;
+
+        ret = xmlTextReaderRead(rec_data->reader);
+        if (ret == 0)
+            errorf("Bad arg 1 to xml_parse(): Premature end of data.\n");
+        else if(ret < 0)
+            errorf("(xml_parse) Error reading XML node.\n");
+
+        switch (xmlTextReaderNodeType(rec_data->reader))
+        {
+            case XML_READER_TYPE_ATTRIBUTE:
+            case XML_READER_TYPE_TEXT:
+            case XML_READER_TYPE_CDATA:
+                errorf("Bad arg 1 to xml_parse(): Start tag expected.\n");
+
+            case XML_READER_TYPE_ELEMENT:
+                break;
+
+            default:
+                continue;
+        }
+    } while (MY_FALSE);
+
+    /* Now parse the XML string. */
+    parse_node(inter_sp, rec_data->reader);
+
+    /* we no longer need the string */
+    free_svalue(sp);
+
+    *sp = *inter_sp;
+    inter_sp--;
+
+    /* At the end, be nice and remove the rest using our error handler. */
+    pop_stack();
+ 
+    return sp;
+}
+ 
+#endif /* USE_XML && HAS_XML2 */
Index: trunk.xml/src/pkg-xml2.h
===================================================================
--- trunk.xml/src/pkg-xml2.h	(Revision 0)
+++ trunk.xml/src/pkg-xml2.h	(Revision 0)
@@ -0,0 +1,16 @@
+#ifndef PKG_XML2_H__
+#define PKG_XML2_H__ 1
+
+#include "driver.h"
+#include "machine.h"
+
+#if defined(USE_XML) && defined(HAS_XML2)
+
+/* --- Prototypes --- */
+
+void pkg_xml2_init();
+
+#endif /* USE_XML && HAS_XML2 */
+
+#endif /* PKG_XML2_H__ */
+
Index: trunk.xml/src/config.h.in
===================================================================
--- trunk.xml/src/config.h.in	(Revision 2554)
+++ trunk.xml/src/config.h.in	(Arbeitskopie)
@@ -381,7 +381,7 @@
 
 /* Define this if you want iksemel library support.
  */
-@cdef_use_iksemel@ USE_IKSEMEL
+@cdef_use_xml@ USE_XML
 
 /* Define this if you want the obsolete and deprecated efuns.
  */
Index: trunk.xml/src/func_spec
===================================================================
--- trunk.xml/src/func_spec	(Revision 2554)
+++ trunk.xml/src/func_spec	(Arbeitskopie)
@@ -706,12 +706,12 @@
 #endif /* USE_MCCP */
 
 
-#ifdef USE_IKSEMEL
+#ifdef USE_XML
 
 string  xml_generate(mixed *);
 mixed  *xml_parse(string);
 
-#endif /* USE_IKSEMEL */
+#endif /* USE_XML */
 
 
 #ifdef USE_MYSQL
Index: trunk.xml/mudlib/sys/xml.h
===================================================================
--- trunk.xml/mudlib/sys/xml.h	(Revision 2554)
+++ trunk.xml/mudlib/sys/xml.h	(Arbeitskopie)
@@ -2,8 +2,8 @@
 #define XML_H__ 1
 
 #define XML_TAG_NAME                    0 /* Name of the current tag */
-#define XML_TAG_ATTRIBUTES              1 /* Atttributes of the current tag */    
-#define XML_TAG_CONTENTS                2 /* Contents of the curren tag */
+#define XML_TAG_ATTRIBUTES              1 /* Atttributes of the current tag */
+#define XML_TAG_CONTENTS                2 /* Contents of the current tag */
 
 #define XML_TAG_SIZE                    3
 
