]> granicus.if.org Git - ejabberd/commitdiff
Switch to rebar build tool
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Mon, 8 Apr 2013 09:12:54 +0000 (11:12 +0200)
committerChristophe Romain <christophe.romain@process-one.net>
Thu, 13 Jun 2013 09:11:02 +0000 (11:11 +0200)
Use dynamic Rebar configuration
Make iconv dependency optional
Disable transient_supervisors compile option
Add hipe compilation support
Only compile ibrowse and lhttpc when needed
Make it possible to generate an OTP application release
Add --enable-debug compile option
Add --enable-all compiler option
Add --enable-tools configure option
Add --with-erlang configure option.
Add --enable-erlang-version-check configure option.
Add lager support
Improve the test suite

322 files changed:
.gitignore
Makefile.in [new file with mode: 0644]
Makefile.win32 [moved from src/Makefile.win32 with 100% similarity]
README
asn1/ELDAPv3.asn1 [moved from src/eldap/ELDAPv3.asn with 100% similarity]
asn1/XmppAddr.asn1 [moved from src/XmppAddr.asn1 with 100% similarity]
autogen.sh [new file with mode: 0755]
configure [moved from src/configure with 58% similarity]
configure.ac [new file with mode: 0644]
configure.bat [moved from src/configure.bat with 100% similarity]
contrib/extract_translations/extract_translations.erl
contrib/extract_translations/prepare-translation.sh
doc/guide.tex
ejabberd.cfg.example [moved from src/ejabberd.cfg.example with 100% similarity]
ejabberd.init.template [moved from src/ejabberd.init.template with 100% similarity]
ejabberdctl.cfg.example [moved from src/ejabberdctl.cfg.example with 100% similarity]
ejabberdctl.template [moved from src/ejabberdctl.template with 91% similarity, mode: 0755]
include/adhoc.hrl [moved from src/adhoc.hrl with 100% similarity]
include/ejabberd.hrl [moved from src/ejabberd.hrl with 71% similarity]
include/ejabberd_commands.hrl [moved from src/ejabberd_commands.hrl with 100% similarity]
include/ejabberd_config.hrl [moved from src/ejabberd_config.hrl with 100% similarity]
include/ejabberd_ctl.hrl [moved from src/ejabberd_ctl.hrl with 100% similarity]
include/ejabberd_http.hrl [moved from src/web/ejabberd_http.hrl with 100% similarity]
include/ejabberd_web_admin.hrl [moved from src/web/ejabberd_web_admin.hrl with 100% similarity]
include/eldap.hrl [moved from src/eldap/eldap.hrl with 100% similarity]
include/http_bind.hrl [moved from src/web/http_bind.hrl with 100% similarity]
include/jlib.hrl [moved from src/jlib.hrl with 73% similarity]
include/logger.hrl [new file with mode: 0644]
include/mod_muc_room.hrl [moved from src/mod_muc/mod_muc_room.hrl with 100% similarity]
include/mod_privacy.hrl [moved from src/mod_privacy.hrl with 100% similarity]
include/mod_proxy65.hrl [moved from src/mod_proxy65/mod_proxy65.hrl with 100% similarity]
include/mod_roster.hrl [moved from src/mod_roster.hrl with 100% similarity]
include/ns.hrl [new file with mode: 0644]
include/pubsub.hrl [moved from src/mod_pubsub/pubsub.hrl with 100% similarity]
inetrc [moved from src/inetrc with 100% similarity]
install-sh [moved from src/install-sh with 100% similarity]
m4/erlang-extra.m4 [new file with mode: 0644]
priv/msgs/ca.msg [moved from src/msgs/ca.msg with 100% similarity]
priv/msgs/ca.po [moved from src/msgs/ca.po with 100% similarity]
priv/msgs/cs.msg [moved from src/msgs/cs.msg with 100% similarity]
priv/msgs/cs.po [moved from src/msgs/cs.po with 100% similarity]
priv/msgs/de.msg [moved from src/msgs/de.msg with 100% similarity]
priv/msgs/de.po [moved from src/msgs/de.po with 100% similarity]
priv/msgs/ejabberd.pot [moved from src/msgs/ejabberd.pot with 100% similarity]
priv/msgs/el.msg [moved from src/msgs/el.msg with 100% similarity]
priv/msgs/el.po [moved from src/msgs/el.po with 100% similarity]
priv/msgs/eo.msg [moved from src/msgs/eo.msg with 100% similarity]
priv/msgs/eo.po [moved from src/msgs/eo.po with 100% similarity]
priv/msgs/es.msg [moved from src/msgs/es.msg with 100% similarity]
priv/msgs/es.po [moved from src/msgs/es.po with 100% similarity]
priv/msgs/fr.msg [moved from src/msgs/fr.msg with 100% similarity]
priv/msgs/fr.po [moved from src/msgs/fr.po with 100% similarity]
priv/msgs/gl.msg [moved from src/msgs/gl.msg with 100% similarity]
priv/msgs/gl.po [moved from src/msgs/gl.po with 100% similarity]
priv/msgs/he.msg [moved from src/msgs/he.msg with 100% similarity]
priv/msgs/he.po [moved from src/msgs/he.po with 100% similarity]
priv/msgs/id.msg [moved from src/msgs/id.msg with 100% similarity]
priv/msgs/id.po [moved from src/msgs/id.po with 100% similarity]
priv/msgs/it.msg [moved from src/msgs/it.msg with 100% similarity]
priv/msgs/it.po [moved from src/msgs/it.po with 100% similarity]
priv/msgs/ja.msg [moved from src/msgs/ja.msg with 100% similarity]
priv/msgs/ja.po [moved from src/msgs/ja.po with 100% similarity]
priv/msgs/nl.msg [moved from src/msgs/nl.msg with 100% similarity]
priv/msgs/nl.po [moved from src/msgs/nl.po with 100% similarity]
priv/msgs/no.msg [moved from src/msgs/no.msg with 100% similarity]
priv/msgs/no.po [moved from src/msgs/no.po with 100% similarity]
priv/msgs/pl.msg [moved from src/msgs/pl.msg with 100% similarity]
priv/msgs/pl.po [moved from src/msgs/pl.po with 100% similarity]
priv/msgs/pt-br.msg [moved from src/msgs/pt-br.msg with 100% similarity]
priv/msgs/pt-br.po [moved from src/msgs/pt-br.po with 100% similarity]
priv/msgs/pt.msg [moved from src/msgs/pt.msg with 100% similarity]
priv/msgs/pt.po [moved from src/msgs/pt.po with 100% similarity]
priv/msgs/ru.msg [moved from src/msgs/ru.msg with 100% similarity]
priv/msgs/ru.po [moved from src/msgs/ru.po with 100% similarity]
priv/msgs/sk.msg [moved from src/msgs/sk.msg with 100% similarity]
priv/msgs/sk.po [moved from src/msgs/sk.po with 100% similarity]
priv/msgs/sv.msg [moved from src/msgs/sv.msg with 100% similarity]
priv/msgs/sv.po [moved from src/msgs/sv.po with 100% similarity]
priv/msgs/th.msg [moved from src/msgs/th.msg with 100% similarity]
priv/msgs/th.po [moved from src/msgs/th.po with 100% similarity]
priv/msgs/tr.msg [moved from src/msgs/tr.msg with 100% similarity]
priv/msgs/tr.po [moved from src/msgs/tr.po with 100% similarity]
priv/msgs/uk.msg [moved from src/msgs/uk.msg with 100% similarity]
priv/msgs/uk.po [moved from src/msgs/uk.po with 100% similarity]
priv/msgs/vi.msg [moved from src/msgs/vi.msg with 100% similarity]
priv/msgs/vi.po [moved from src/msgs/vi.po with 100% similarity]
priv/msgs/wa.msg [moved from src/msgs/wa.msg with 100% similarity]
priv/msgs/wa.po [moved from src/msgs/wa.po with 100% similarity]
priv/msgs/zh.msg [moved from src/msgs/zh.msg with 100% similarity]
priv/msgs/zh.po [moved from src/msgs/zh.po with 100% similarity]
rebar [new file with mode: 0755]
rebar.config.script [new file with mode: 0644]
rel/files/erl [new file with mode: 0755]
rel/files/install_upgrade.escript [new file with mode: 0644]
rel/reltool.config.script [new file with mode: 0644]
sql/mssql2000.sql [moved from src/odbc/mssql2000.sql with 100% similarity]
sql/mssql2005.sql [moved from src/odbc/mssql2005.sql with 100% similarity]
sql/mysql.sql [moved from src/odbc/mysql.sql with 100% similarity]
sql/pg.sql [moved from src/odbc/pg.sql with 100% similarity]
src/Makefile.in [deleted file]
src/acinclude.m4 [deleted file]
src/acl.erl
src/adhoc.erl
src/cache_tab.erl [deleted file]
src/cache_tab_sup.erl [deleted file]
src/config.guess [deleted file]
src/config.sub [deleted file]
src/configure.ac [deleted file]
src/configure.erl
src/cyrsasl.erl
src/cyrsasl_digest.erl
src/cyrsasl_scram.erl
src/dynamic_compile.erl [deleted file]
src/ejabberd.app [deleted file]
src/ejabberd.app.src.in [new file with mode: 0644]
src/ejabberd.erl
src/ejabberd_admin.erl
src/ejabberd_app.erl
src/ejabberd_auth.erl
src/ejabberd_auth_anonymous.erl
src/ejabberd_auth_external.erl
src/ejabberd_auth_internal.erl
src/ejabberd_auth_ldap.erl
src/ejabberd_auth_odbc.erl
src/ejabberd_auth_pam.erl
src/ejabberd_c2s.erl
src/ejabberd_captcha.erl
src/ejabberd_check.erl
src/ejabberd_commands.erl
src/ejabberd_config.erl
src/ejabberd_ctl.erl
src/ejabberd_frontend_socket.erl
src/ejabberd_hooks.erl
src/ejabberd_http.erl [moved from src/web/ejabberd_http.erl with 99% similarity]
src/ejabberd_http_bind.erl [moved from src/web/ejabberd_http_bind.erl with 99% similarity]
src/ejabberd_http_poll.erl [moved from src/web/ejabberd_http_poll.erl with 99% similarity]
src/ejabberd_listener.erl
src/ejabberd_local.erl
src/ejabberd_logger.erl [new file with mode: 0644]
src/ejabberd_logger_h.erl [deleted file]
src/ejabberd_loglevel.erl [deleted file]
src/ejabberd_odbc.erl [moved from src/odbc/ejabberd_odbc.erl with 99% similarity]
src/ejabberd_odbc_sup.erl [moved from src/odbc/ejabberd_odbc_sup.erl with 99% similarity]
src/ejabberd_piefxis.erl
src/ejabberd_rdbms.erl
src/ejabberd_receiver.erl
src/ejabberd_router.erl
src/ejabberd_s2s.erl
src/ejabberd_s2s_in.erl
src/ejabberd_s2s_out.erl
src/ejabberd_service.erl
src/ejabberd_sm.erl
src/ejabberd_socket.erl
src/ejabberd_sup.erl
src/ejabberd_system_monitor.erl
src/ejabberd_update.erl
src/ejabberd_web.erl [moved from src/web/ejabberd_web.erl with 99% similarity]
src/ejabberd_web_admin.erl [moved from src/web/ejabberd_web_admin.erl with 99% similarity]
src/ejabberd_zlib/Makefile.in [deleted file]
src/ejabberd_zlib/Makefile.win32 [deleted file]
src/ejabberd_zlib/ejabberd_zlib.erl [deleted file]
src/ejabberd_zlib/ejabberd_zlib_drv.c [deleted file]
src/eldap.erl [moved from src/eldap/eldap.erl with 99% similarity]
src/eldap/Makefile.in [deleted file]
src/eldap/Makefile.win32 [deleted file]
src/eldap_filter.erl [moved from src/eldap/eldap_filter.erl with 100% similarity]
src/eldap_filter_yecc.yrl [moved from src/eldap/eldap_filter_yecc.yrl with 100% similarity]
src/eldap_pool.erl [moved from src/eldap/eldap_pool.erl with 99% similarity]
src/eldap_utils.erl [moved from src/eldap/eldap_utils.erl with 99% similarity]
src/expat_erl.c [deleted file]
src/extauth.erl
src/gen_iq_handler.erl
src/gen_mod.erl
src/gen_pubsub_node.erl [moved from src/mod_pubsub/gen_pubsub_node.erl with 100% similarity]
src/gen_pubsub_nodetree.erl [moved from src/mod_pubsub/gen_pubsub_nodetree.erl with 100% similarity]
src/jd2ejd.erl
src/jlib.erl
src/mod_adhoc.erl
src/mod_announce.erl
src/mod_blocking.erl
src/mod_caps.erl
src/mod_carboncopy.erl
src/mod_configure.erl
src/mod_configure2.erl
src/mod_disco.erl
src/mod_echo.erl
src/mod_http_bind.erl [moved from src/web/mod_http_bind.erl with 99% similarity]
src/mod_http_fileserver.erl [moved from src/web/mod_http_fileserver.erl with 99% similarity]
src/mod_ip_blacklist.erl
src/mod_irc.erl [moved from src/mod_irc/mod_irc.erl with 99% similarity]
src/mod_irc/Makefile.in [deleted file]
src/mod_irc/Makefile.win32 [deleted file]
src/mod_irc/iconv.erl [deleted file]
src/mod_irc/iconv_erl.c [deleted file]
src/mod_irc_connection.erl [moved from src/mod_irc/mod_irc_connection.erl with 99% similarity]
src/mod_last.erl
src/mod_muc.erl [moved from src/mod_muc/mod_muc.erl with 99% similarity]
src/mod_muc/Makefile.in [deleted file]
src/mod_muc/Makefile.win32 [deleted file]
src/mod_muc_log.erl [moved from src/mod_muc/mod_muc_log.erl with 99% similarity]
src/mod_muc_room.erl [moved from src/mod_muc/mod_muc_room.erl with 99% similarity]
src/mod_offline.erl
src/mod_ping.erl
src/mod_pres_counter.erl
src/mod_privacy.erl
src/mod_private.erl
src/mod_proxy65.erl [moved from src/mod_proxy65/mod_proxy65.erl with 100% similarity]
src/mod_proxy65/Makefile.in [deleted file]
src/mod_proxy65/Makefile.win32 [deleted file]
src/mod_proxy65_lib.erl [moved from src/mod_proxy65/mod_proxy65_lib.erl with 100% similarity]
src/mod_proxy65_service.erl [moved from src/mod_proxy65/mod_proxy65_service.erl with 99% similarity]
src/mod_proxy65_sm.erl [moved from src/mod_proxy65/mod_proxy65_sm.erl with 100% similarity]
src/mod_proxy65_stream.erl [moved from src/mod_proxy65/mod_proxy65_stream.erl with 99% similarity]
src/mod_pubsub.erl [moved from src/mod_pubsub/mod_pubsub.erl with 99% similarity]
src/mod_pubsub/Makefile.in [deleted file]
src/mod_pubsub/Makefile.win32 [deleted file]
src/mod_pubsub_odbc.erl [moved from src/mod_pubsub/mod_pubsub_odbc.erl with 99% similarity]
src/mod_register.erl
src/mod_register_web.erl [moved from src/web/mod_register_web.erl with 99% similarity]
src/mod_roster.erl
src/mod_service_log.erl
src/mod_shared_roster.erl
src/mod_shared_roster_ldap.erl
src/mod_sic.erl
src/mod_stats.erl
src/mod_time.erl
src/mod_vcard.erl
src/mod_vcard_ldap.erl
src/mod_vcard_xupdate.erl
src/mod_version.erl
src/mysql/COPYING [deleted file]
src/mysql/Makefile.in [deleted file]
src/mysql/Makefile.win32 [deleted file]
src/mysql/mysql.erl [deleted file]
src/mysql/mysql.hrl [deleted file]
src/mysql/mysql_auth.erl [deleted file]
src/mysql/mysql_conn.erl [deleted file]
src/mysql/mysql_recv.erl [deleted file]
src/node.template [moved from src/mod_pubsub/node.template with 100% similarity]
src/node_buddy.erl [moved from src/mod_pubsub/node_buddy.erl with 100% similarity]
src/node_club.erl [moved from src/mod_pubsub/node_club.erl with 100% similarity]
src/node_dag.erl [moved from src/mod_pubsub/node_dag.erl with 100% similarity]
src/node_dispatch.erl [moved from src/mod_pubsub/node_dispatch.erl with 100% similarity]
src/node_flat.erl [moved from src/mod_pubsub/node_flat.erl with 100% similarity]
src/node_flat_odbc.erl [moved from src/mod_pubsub/node_flat_odbc.erl with 100% similarity]
src/node_hometree.erl [moved from src/mod_pubsub/node_hometree.erl with 100% similarity]
src/node_hometree_odbc.erl [moved from src/mod_pubsub/node_hometree_odbc.erl with 100% similarity]
src/node_mb.erl [moved from src/mod_pubsub/node_mb.erl with 99% similarity]
src/node_pep.erl [moved from src/mod_pubsub/node_pep.erl with 99% similarity]
src/node_pep_odbc.erl [moved from src/mod_pubsub/node_pep_odbc.erl with 99% similarity]
src/node_private.erl [moved from src/mod_pubsub/node_private.erl with 100% similarity]
src/node_public.erl [moved from src/mod_pubsub/node_public.erl with 100% similarity]
src/nodetree_dag.erl [moved from src/mod_pubsub/nodetree_dag.erl with 99% similarity]
src/nodetree_tree.erl [moved from src/mod_pubsub/nodetree_tree.erl with 100% similarity]
src/nodetree_tree_odbc.erl [moved from src/mod_pubsub/nodetree_tree_odbc.erl with 100% similarity]
src/nodetree_virtual.erl [moved from src/mod_pubsub/nodetree_virtual.erl with 100% similarity]
src/odbc/Makefile.in [deleted file]
src/odbc/Makefile.win32 [deleted file]
src/odbc_queries.erl [moved from src/odbc/odbc_queries.erl with 99% similarity]
src/pam/Makefile.in [deleted file]
src/pam/epam.c [deleted file]
src/pam/epam.erl [deleted file]
src/pgsql/EPLICENSE [deleted file]
src/pgsql/Makefile.in [deleted file]
src/pgsql/Makefile.win32 [deleted file]
src/pgsql/pgsql.erl [deleted file]
src/pgsql/pgsql_proto.erl [deleted file]
src/pgsql/pgsql_tcp.erl [deleted file]
src/pgsql/pgsql_util.erl [deleted file]
src/pubsub_db_odbc.erl [moved from src/mod_pubsub/pubsub_db_odbc.erl with 100% similarity]
src/pubsub_index.erl [moved from src/mod_pubsub/pubsub_index.erl with 100% similarity]
src/pubsub_odbc.patch [moved from src/mod_pubsub/pubsub_odbc.patch with 100% similarity]
src/pubsub_subscription.erl [moved from src/mod_pubsub/pubsub_subscription.erl with 100% similarity]
src/pubsub_subscription_odbc.erl [moved from src/mod_pubsub/pubsub_subscription_odbc.erl with 100% similarity]
src/sha.erl [deleted file]
src/shaper.erl
src/stringprep/Makefile.in [deleted file]
src/stringprep/Makefile.win32 [deleted file]
src/stringprep/stringprep.erl [deleted file]
src/stringprep/stringprep_drv.c [deleted file]
src/stringprep/stringprep_sup.erl [deleted file]
src/stringprep/uni_data.c [deleted file]
src/stringprep/uni_norm.c [deleted file]
src/stringprep/uni_parse.tcl [deleted file]
src/stringprep/uni_parse2.tcl [deleted file]
src/stun/Makefile.in [deleted file]
src/stun/Makefile.win32 [deleted file]
src/stun/ejabberd_stun.erl [deleted file]
src/stun/stun.hrl [deleted file]
src/stun/stun_codec.erl [deleted file]
src/tls/Makefile.in [deleted file]
src/tls/Makefile.win32 [deleted file]
src/tls/sha_drv.c [deleted file]
src/tls/stdint.h [deleted file]
src/tls/tls.erl [deleted file]
src/tls/tls_drv.c [deleted file]
src/translate.erl
src/web/Makefile.in [deleted file]
src/web/Makefile.win32 [deleted file]
src/win32_dns.erl
src/xml.c [deleted file]
src/xml.erl [deleted file]
src/xml_stream.erl [deleted file]
test/ejabberd_SUITE.erl [new file with mode: 0644]
test/ejabberd_SUITE_data/ejabberd.cfg [new file with mode: 0644]
tools/p1_prof.erl [moved from src/p1_prof.erl with 83% similarity]
tools/xmpp_codec.erl [new file with mode: 0644]
tools/xmpp_codec.hrl [new file with mode: 0644]
tools/xmpp_codec.spec [new file with mode: 0644]
vars.config.in [new file with mode: 0644]
win32/CheckReqs.ini [moved from src/win32/CheckReqs.ini with 100% similarity]
win32/CheckReqs1.ini [moved from src/win32/CheckReqs1.ini with 100% similarity]
win32/CheckReqs1H.ini [moved from src/win32/CheckReqs1H.ini with 100% similarity]
win32/CheckService.ini [moved from src/win32/CheckService.ini with 100% similarity]
win32/CheckUser.ini [moved from src/win32/CheckUser.ini with 100% similarity]
win32/CheckUserH.ini [moved from src/win32/CheckUserH.ini with 100% similarity]
win32/ejabberd.cfg [moved from src/win32/ejabberd.cfg with 100% similarity]
win32/ejabberd.ico [moved from src/win32/ejabberd.ico with 100% similarity]
win32/ejabberd.nsi [moved from src/win32/ejabberd.nsi with 100% similarity]
win32/ejabberd_header.bmp [moved from src/win32/ejabberd_header.bmp with 100% similarity]
win32/ejabberd_intro.bmp [moved from src/win32/ejabberd_intro.bmp with 100% similarity]
win32/inetrc [moved from src/win32/inetrc with 100% similarity]

index 60f1a2614dd9a65c6aa571442ccaf432956ed757..348ab660f79acf966697d436eba4964e9c738f69 100644 (file)
@@ -2,7 +2,15 @@
 # You can add personal rules in your file .git/info/exclude
 *.swp
 *~
+\#*#
+.#*
+/Makefile
+/config.log
+/config.status
+/aclocal.m4
 /contrib/extract_translations/extract_translations.beam
+/*.cache
+/deps/
 /doc/*.aux
 /doc/*.haux
 /doc/*.html
 /doc/*.toc
 /doc/contributed_modules.tex
 /doc/version.tex
-/src/*.beam
-/src/*.so
-/src/*.so.dSYM
-/src/*/*.beam
-/src/*/Makefile
-/src/Makefile
+/ebin/*.beam
+/ebin/ejabberd.app
+/include/ELDAPv3.hrl
+/include/XmppAddr.hrl
+/src/ELDAPv3.asn1db
+/src/ELDAPv3.erl
 /src/XmppAddr.asn1db
 /src/XmppAddr.erl
-/src/XmppAddr.hrl
-/src/aclocal.m4
-/src/autom4te.cache
-/src/config.log
-/src/config.status
-/src/ejabberd.init
-/src/ejabberdctl.example
-/src/eldap/ELDAPv3.asn1db
-/src/eldap/ELDAPv3.erl
-/src/eldap/ELDAPv3.hrl
-/src/eldap/eldap_filter_yecc.erl
-/src/epam
+/src/ejabberd.app.src
+/src/eldap_filter_yecc.erl
+/vars.config
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..d695802
--- /dev/null
@@ -0,0 +1,257 @@
+REBAR = @ESCRIPT@ rebar
+INSTALL = @INSTALL@
+SED = @SED@
+ERL = @ERL@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+DESTDIR =
+
+# /etc/ejabberd/
+ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
+
+# /sbin/
+SBINDIR = $(DESTDIR)@sbindir@
+
+# /lib/ejabberd/
+EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd
+
+# /share/doc/ejabberd
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+datarootdir = @datarootdir@
+DOCDIR = $(DESTDIR)@docdir@
+
+# /usr/lib/ejabberd/ebin/
+BEAMDIR = $(EJABBERDDIR)/ebin
+
+# /usr/lib/ejabberd/include/
+INCLUDEDIR = $(EJABBERDDIR)/include
+
+# /usr/lib/ejabberd/priv/
+PRIVDIR = $(EJABBERDDIR)/priv
+
+# /usr/lib/ejabberd/priv/bin
+PBINDIR = $(PRIVDIR)/bin
+
+# /usr/lib/ejabberd/priv/lib
+SODIR = $(PRIVDIR)/lib
+
+# /usr/lib/ejabberd/priv/msgs
+MSGSDIR = $(PRIVDIR)/msgs
+
+# /var/lib/ejabberd/
+SPOOLDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
+
+# /var/lock/ejabberdctl
+CTLLOCKDIR = $(DESTDIR)@localstatedir@/lock/ejabberdctl
+
+# /var/lib/ejabberd/.erlang.cookie
+COOKIEFILE = $(SPOOLDIR)/.erlang.cookie
+
+# /var/log/ejabberd/
+LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
+
+INSTALLUSER=@INSTALLUSER@
+# if no user was enabled, don't set privileges or ownership
+ifeq ($(INSTALLUSER),)
+  O_USER=
+  G_USER=
+  CHOWN_COMMAND=echo
+  CHOWN_OUTPUT=/dev/null
+  INIT_USER=root
+else
+  O_USER=-o $(INSTALLUSER)
+  G_USER=-g $(INSTALLUSER)
+  CHOWN_COMMAND=chown
+  CHOWN_OUTPUT=&1
+  INIT_USER=$(INSTALLUSER)
+endif
+
+all: deps src
+
+deps: deps/.got
+
+deps/.got:
+       rm -rf deps/.got
+       rm -rf deps/.built
+       $(REBAR) get-deps && :> deps/.got
+
+deps/.built:
+       $(REBAR) compile && :> deps/.built
+
+src: deps/.built
+       $(REBAR) skip_deps=true compile
+
+update:
+       rm -rf deps/.got
+       rm -rf deps/.built
+       $(REBAR) update-deps && :> deps/.got
+
+translations:
+       contrib/extract_translations/prepare-translation.sh -updateall
+
+doc:
+       echo making $$target in doc; \
+       (cd doc && $(MAKE) $$target) || exit 1
+
+edoc:
+       $(ERL) -noinput +B -eval \
+        'case edoc:application(ejabberd, ".", []) of ok -> halt(0); error -> halt(1) end.'
+
+spec:
+       $(ERL) -noinput +B -pa ebin -pa deps/*/ebin -eval \
+       'case xml_gen:compile("tools/xmpp_codec.spec") of ok -> halt(0); _ -> halt(1) end.'
+
+install: all
+       #
+       # Configuration files
+       $(INSTALL) -d -m 750 $(G_USER) $(ETCDIR)
+       [ -f $(ETCDIR)/ejabberd.cfg ] \
+               && $(INSTALL) -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new \
+               || $(INSTALL) -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
+       $(SED) -e "s*{{rootdir}}*@prefix@*" \
+               -e "s*{{installuser}}*@INSTALLUSER@*" \
+               -e "s*{{libdir}}*@libdir@*" \
+               -e "s*{{sysconfdir}}*@sysconfdir@*" \
+               -e "s*{{localstatedir}}*@localstatedir@*" \
+               -e "s*{{docdir}}*@docdir@*" \
+               -e "s*{{erl}}*@ERL@*" ejabberdctl.template \
+               > ejabberdctl.example
+       [ -f $(ETCDIR)/ejabberdctl.cfg ] \
+               && $(INSTALL) -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new \
+               || $(INSTALL) -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
+       $(INSTALL) -b -m 644 $(G_USER) inetrc $(ETCDIR)/inetrc
+       #
+       # Administration script
+       [ -d $(SBINDIR) ] || $(INSTALL) -d -m 755 $(SBINDIR)
+       $(INSTALL) -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
+       #
+       # Init script
+       $(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*" \
+               -e "s*@installuser@*$(INIT_USER)*" ejabberd.init.template \
+               > ejabberd.init
+       chmod 755 ejabberd.init
+       #
+       # Binary Erlang files
+       $(INSTALL) -d $(BEAMDIR)
+       $(INSTALL) -m 644 ebin/*.app $(BEAMDIR)
+       $(INSTALL) -m 644 ebin/*.beam $(BEAMDIR)
+       $(INSTALL) -m 644 deps/*/ebin/*.app $(BEAMDIR)
+       $(INSTALL) -m 644 deps/*/ebin/*.beam $(BEAMDIR)
+       rm -f $(BEAMDIR)/configure.beam
+       #
+       # ejabberd header files
+       $(INSTALL) -d $(INCLUDEDIR)
+       $(INSTALL) -m 644 include/*.hrl $(INCLUDEDIR)
+       $(INSTALL) -m 644 deps/*/include/*.hrl $(INCLUDEDIR)
+       #
+       # Binary C programs
+       $(INSTALL) -d $(PBINDIR)
+       $(INSTALL) -m 750 $(O_USER) tools/captcha.sh $(PBINDIR)
+       #
+       # Binary system libraries
+       $(INSTALL) -d $(SODIR)
+       #$(INSTALL) -m 644 priv/lib/*.so $(SODIR)
+       $(INSTALL) -m 644 deps/*/priv/lib/*.so $(SODIR)
+       #
+       # Translated strings
+       $(INSTALL) -d $(MSGSDIR)
+       $(INSTALL) -m 644 priv/msgs/*.msg $(MSGSDIR)
+       #
+       # Spool directory
+       $(INSTALL) -d -m 750 $(O_USER) $(SPOOLDIR)
+       $(CHOWN_COMMAND) -R @INSTALLUSER@ $(SPOOLDIR) >$(CHOWN_OUTPUT)
+       chmod -R 750 $(SPOOLDIR)
+       [ ! -f $(COOKIEFILE) ] || { $(CHOWN_COMMAND) @INSTALLUSER@ $(COOKIEFILE) >$(CHOWN_OUTPUT) ; chmod 400 $(COOKIEFILE) ; }
+       #
+       # ejabberdctl lock directory
+       $(INSTALL) -d -m 750 $(O_USER) $(CTLLOCKDIR)
+       $(CHOWN_COMMAND) -R @INSTALLUSER@ $(CTLLOCKDIR) >$(CHOWN_OUTPUT)
+       chmod -R 750 $(CTLLOCKDIR)
+       #
+       # Log directory
+       $(INSTALL) -d -m 750 $(O_USER) $(LOGDIR)
+       $(CHOWN_COMMAND) -R @INSTALLUSER@ $(LOGDIR) >$(CHOWN_OUTPUT)
+       chmod -R 750 $(LOGDIR)
+       #
+       # Documentation
+       $(INSTALL) -d $(DOCDIR)
+       $(INSTALL) -m 644 doc/dev.html $(DOCDIR)
+       $(INSTALL) -m 644 doc/guide.html $(DOCDIR)
+       $(INSTALL) -m 644 doc/*.png $(DOCDIR)
+       $(INSTALL) -m 644 doc/*.txt $(DOCDIR)
+       [ -f doc/guide.pdf ] \
+               && $(INSTALL) -m 644 doc/guide.pdf $(DOCDIR) \
+               || echo "No doc/guide.pdf was built"
+       $(INSTALL) -m 644 COPYING $(DOCDIR)
+
+uninstall: uninstall-binary
+
+uninstall-binary:
+       rm -f  $(SBINDIR)/ejabberdctl
+       rm -fr $(DOCDIR)
+       rm -f  $(BEAMDIR)/*.beam
+       rm -f  $(BEAMDIR)/*.app
+       rm -fr $(BEAMDIR)
+       rm -f  $(INCLUDEDIR)/*.hrl
+       rm -fr $(INCLUDEDIR)
+       rm -fr $(PBINDIR)
+       rm -f  $(SODIR)/*.so
+       rm -fr $(SODIR)
+       rm -f  $(MSGSDIR)/*.msgs
+       rm -fr $(MSGSDIR)
+       rm -fr $(PRIVDIR)
+       rm -fr $(EJABBERDDIR)
+
+uninstall-all: uninstall-binary
+       rm -rf $(ETCDIR)
+       rm -rf $(EJABBERDDIR)
+       rm -rf $(SPOOLDIR)
+       rm -rf $(CTLLOCKDIR)
+       rm -rf $(LOGDIR)
+
+clean:
+       rm -rf deps/.got
+       rm -rf deps/.built
+       $(REBAR) clean
+
+clean-rel:
+       rm -rf rel/ejabberd
+
+distclean: clean clean-rel
+       rm -f config.status
+       rm -f config.log
+       rm -rf autom4te.cache
+       rm -rf deps
+       rm -rf ebin
+       rm -f Makefile
+       rm -f vars.config
+       rm -f src/ejabberd.app.src
+       [ ! -f ../ChangeLog ] || rm -f ../ChangeLog
+
+rel: all
+       $(REBAR) generate
+
+TAGS:
+       etags *.erl
+
+Makefile: Makefile.in
+
+erlang.plt:
+       -dialyzer --build_plt --output_plt erlang.plt \
+       --apps kernel stdlib sasl crypto public_key ssl mnesia \
+       inets odbc tools compiler erts webtool runtime_tools asn1 \
+       observer xmerl et gs wx syntax_tools deps/*/ebin
+
+plt: erlang.plt
+
+dialyzer: plt
+       -dialyzer --plt erlang.plt --add_to_plt --output_plt ejabberd.plt \
+       --get_warnings -o dialyzer.log ebin
+
+test:
+       $(REBAR) skip_deps=true ct
+
+.PHONY: src doc edoc dialyzer Makefile TAGS clean clean-rel distclean rel plt \
+       install uninstall uninstall-binary uninstall-all translations deps test spec
similarity index 100%
rename from src/Makefile.win32
rename to Makefile.win32
diff --git a/README b/README
index fafd2ad32677d0dd4bad33e77ac259826c571bc1..2d084603ee47694e6678ea53886c2a9b384400e3 100644 (file)
--- a/README
+++ b/README
@@ -13,8 +13,6 @@ To compile ejabberd you need:
  - OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
  - Zlib 1.2.3 or higher, for Stream Compression support
    (XEP-0138). Optional.
- - Erlang mysql library. Optional. MySQL authentication/storage.
- - Erlang pgsql library. Optional. PostgreSQL authentication/storage.
  - PAM library. Optional. For Pluggable Authentication Modules (PAM).
  - GNU Iconv 1.8 or higher, for the IRC Transport
    (mod_irc). Optional. Not needed on systems with GNU Libc.
@@ -24,7 +22,7 @@ To compile ejabberd you need:
 
 1. Compile and install on *nix systems
 
-To compile ejabberd, go to the directory src/ and execute the commands:
+To compile ejabberd execute the commands:
   ./configure
   make
 
similarity index 100%
rename from src/eldap/ELDAPv3.asn
rename to asn1/ELDAPv3.asn1
similarity index 100%
rename from src/XmppAddr.asn1
rename to asn1/XmppAddr.asn1
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..58209a3
--- /dev/null
@@ -0,0 +1,3 @@
+# generate a new autoconf
+aclocal -I m4
+autoconf
\ No newline at end of file
similarity index 58%
rename from src/configure
rename to configure
index 5347cc483d687eead3ab2dfee944a667cf927d70..6fe74ff015486355936a3d2b4086b237ec6b7eb5 100755 (executable)
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for ejabberd 13.03-beta2.
+# Generated by GNU Autoconf 2.67 for ejabberd 3.0.0.
 #
 # Report bugs to <ejabberd@process-one.net>.
 #
@@ -91,7 +91,6 @@ fi
 IFS=" ""       $as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -217,18 +216,11 @@ IFS=$as_save_IFS
   # We cannot yet assume a decent shell, so we have to provide a
        # neutralization value for shells without unset; and this also
        # works around shells that cannot unset nonexistent variables.
-       # Preserve -v and -x to the replacement shell.
        BASH_ENV=/dev/null
        ENV=/dev/null
        (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
        export CONFIG_SHELL
-       case $- in # ((((
-         *v*x* | *x*v* ) as_opts=-vx ;;
-         *v* ) as_opts=-v ;;
-         *x* ) as_opts=-x ;;
-         * ) as_opts= ;;
-       esac
-       exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+       exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
 fi
 
     if test x$as_have_required = xno; then :
@@ -560,115 +552,64 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='ejabberd'
 PACKAGE_TARNAME='ejabberd'
-PACKAGE_VERSION='13.03-beta2'
-PACKAGE_STRING='ejabberd 13.03-beta2'
+PACKAGE_VERSION='3.0.0'
+PACKAGE_STRING='ejabberd 3.0.0'
 PACKAGE_BUGREPORT='ejabberd@process-one.net'
 PACKAGE_URL=''
 
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
 ac_default_prefix=/
 ac_subst_vars='LTLIBOBJS
-ERLCFLAGS
-target_os
-target_vendor
-target_cpu
-target
-host_os
-host_vendor
-host_cpu
-host
-build_os
-build_vendor
-build_cpu
-build
-md2
-INSTALLUSER
-SSL_CFLAGS
-SSL_LIBS
+LIBOBJS
+tools
+lager
+http
+debug
+iconv
+json
+stun
+zlib
+pam
+pgsql
+mysql
+odbc
+db_type
 nif
 full_xml
 transient_supervisors
-db_type
 roster_gateway_workaround
 hipe
-PAM_LIBS
-PAM_CFLAGS
-make_pam
-pam
-ZLIB_LIBS
-ZLIB_CFLAGS
-make_ejabberd_zlib
-ejabberd_zlib
-make_web
-web
-make_tls
-tls
-make_odbc
-odbc
-make_eldap
-eldap
-make_mod_pubsub
-mod_pubsub
-make_mod_proxy65
-mod_proxy65
-make_mod_muc
-mod_muc
-make_mod_irc
-mod_irc
-LIBOBJS
-EXPAT_LIBS
-EXPAT_CFLAGS
-EGREP
-GREP
-CPP
-LIBICONV
-ERLANG_LIBS
-ERLANG_CFLAGS
-ERL
+ERLANG_LIB_VER_runtime_tools
+ERLANG_LIB_DIR_runtime_tools
+ERLANG_LIB_VER_tools
+ERLANG_LIB_DIR_tools
+ERLANG_LIB_VER_odbc
+ERLANG_LIB_DIR_odbc
+ERLANG_LIB_VER_compiler
+ERLANG_LIB_DIR_compiler
+ERLANG_LIB_VER_inets
+ERLANG_LIB_DIR_inets
+ERLANG_LIB_VER_mnesia
+ERLANG_LIB_DIR_mnesia
+ERLANG_LIB_VER_ssl
+ERLANG_LIB_DIR_ssl
+ERLANG_LIB_VER_public_key
+ERLANG_LIB_DIR_public_key
+ERLANG_LIB_VER_crypto
+ERLANG_LIB_DIR_crypto
+ERLANG_LIB_VER_sasl
+ERLANG_LIB_DIR_sasl
+INSTALLUSER
+MAKE
+ESCRIPT
+ERLANG_ROOT_DIR
+ERLCFLAGS
 ERLC
+ERL
+SED
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
 SET_MAKE
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
 target_alias
 host_alias
 build_alias
@@ -711,38 +652,32 @@ ac_subst_files=''
 ac_user_opts='
 enable_option_checking
 with_erlang
-with_libiconv_prefix
-with_expat
-enable_mod_irc
-enable_mod_muc
-enable_mod_proxy65
-enable_mod_pubsub
-enable_eldap
-enable_odbc
-enable_tls
-enable_web
-enable_ejabberd_zlib
-with_zlib
-enable_pam
-with_pam
+enable_erlang_version_check
 enable_hipe
 enable_roster_gateway_workaround
-enable_mssql
 enable_transient_supervisors
 enable_full_xml
+enable_mssql
+enable_tools
+enable_all
 enable_nif
-with_openssl
+enable_odbc
+enable_mysql
+enable_pgsql
+enable_pam
+enable_zlib
+enable_stun
+enable_json
+enable_iconv
+enable_debug
+enable_http
+enable_lager
 enable_user
 '
       ac_precious_vars='build_alias
 host_alias
 target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CPP
+ERL
 ERLC
 ERLCFLAGS'
 
@@ -1149,7 +1084,7 @@ Try \`$0 --help' for more information"
     $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
     ;;
 
   esac
@@ -1287,7 +1222,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures ejabberd 13.03-beta2 to adapt to many kinds of systems.
+\`configure' configures ejabberd 3.0.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1343,17 +1278,12 @@ Fine tuning of the installation directories:
 _ACEOF
 
   cat <<\_ACEOF
-
-System types:
-  --build=BUILD     configure for building on BUILD [guessed]
-  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
-  --target=TARGET   configure for building compilers for TARGET [HOST]
 _ACEOF
 fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of ejabberd 13.03-beta2:";;
+     short | recursive ) echo "Configuration of ejabberd 3.0.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1361,30 +1291,42 @@ Optional Features:
   --disable-option-checking  ignore unrecognized --enable/--with options
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --enable-mod_irc        enable mod_irc (default: yes)
-  --enable-mod_muc        enable mod_muc (default: yes)
-  --enable-mod_proxy65    enable mod_proxy65 (default: yes)
-  --enable-mod_pubsub     enable mod_pubsub (default: yes)
-  --enable-eldap          enable eldap (default: yes)
-  --enable-odbc           enable odbc (default: no)
-  --enable-tls            enable tls (default: yes)
-  --enable-web            enable web (default: yes)
-  --enable-ejabberd_zlib  enable ejabberd_zlib (default: yes)
-  --enable-pam            enable pam (default: no)
+  --enable-erlang-version-check
+                          Check Erlang/OTP version [default=yes]
   --enable-hipe           compile natively with HiPE, not recommended
                           (default: no)
   --enable-roster-gateway-workaround
                           turn on workaround for processing gateway
                           subscriptions (default: no)
-  --enable-mssql          use Microsoft SQL Server database (default: no,
-                          requires --enable-odbc)
   --enable-transient_supervisors
                           use Erlang supervision for transient process
-                          (default: yes)
+                          (default: no)
   --enable-full-xml       use XML features in XMPP stream (ex: CDATA)
                           (default: no, requires XML compliant clients)
+  --enable-mssql          use Microsoft SQL Server database (default: no,
+                          requires --enable-odbc)
+  --enable-tools          build development tools (currently the ejabberd
+                          profiler only, default: no)
+  --enable-all            same as --enable-nif --enable-odbc --enable-mysql
+                          --enable-pgsql --enable-pam --enable-zlib
+                          --enable-stun --enable-json --enable-iconv
+                          --enable-debug --enable-http (useful for Dialyzer
+                          checks, default: no)
   --enable-nif            replace some functions with C equivalents. Requires
                           Erlang R13B04 or higher (default: no)
+  --enable-odbc           enable pure ODBC support (default: no)
+  --enable-mysql          enable MySQL support (default: no)
+  --enable-pgsql          enable PostgreSQL support (default: no)
+  --enable-pam            enable PAM support (default: no)
+  --enable-zlib           enable Stream Compression (XEP-0138) using zlib
+                          (default: yes)
+  --enable-stun           enable STUN support (default: no)
+  --enable-json           enable JSON support for mod_bosh (default: no)
+  --enable-iconv          enable iconv support (default: yes)
+  --enable-debug          enable debug information (default: yes)
+  --enable-http           build external HTTP libraries ('ibrowse' and
+                          'lhttpc', default: no)
+  --enable-lager          enable lager support (default: yes)
   --enable-user[[[=USER]]]
                           allow this system user to start ejabberd (default:
                           no)
@@ -1392,23 +1334,10 @@ Optional Features:
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --with-erlang=PREFIX    path to erlc and erl
-  --with-libiconv-prefix=PREFIX
-                          prefix where libiconv is installed
-  --with-expat=PREFIX     prefix where EXPAT is installed
-  --with-zlib=PREFIX      prefix where zlib is installed
-  --with-pam=PREFIX       prefix where PAM is installed
-  --with-openssl=PREFIX   prefix where OPENSSL is installed
+  --with-erlang=dir       search for erlang in dir
 
 Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
-              you have headers in a nonstandard directory <include dir>
-  CPP         C preprocessor
+  ERL         Erlang/OTP interpreter command [autodetected]
   ERLC        Erlang/OTP compiler command [autodetected]
   ERLCFLAGS   Erlang/OTP compiler flags [none]
 
@@ -1478,8 +1407,8 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-ejabberd configure 13.03-beta2
-generated by GNU Autoconf 2.68
+ejabberd configure 3.0.0
+generated by GNU Autoconf 2.67
 
 Copyright (C) 2010 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
@@ -1492,291 +1421,6 @@ fi
 ## Autoconf initialization. ##
 ## ------------------------ ##
 
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
-  if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-        test "$cross_compiling" = yes ||
-        $as_test_x conftest$ac_exeext
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=1
-fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
-        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-    ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## --------------------------------------- ##
-## Report this to ejabberd@process-one.net ##
-## --------------------------------------- ##"
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_compile
-
 # ac_fn_erl_try_run LINENO
 # ------------------------
 # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
@@ -1814,7 +1458,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_retval=$ac_status
 fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
   as_fn_set_status $ac_retval
 
 } # ac_fn_erl_try_run
@@ -1822,8 +1466,8 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by ejabberd $as_me 13.03-beta2, which was
-generated by GNU Autoconf 2.68.  Invocation command line was
+It was created by ejabberd $as_me 3.0.0, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
 
   $ $0 $@
 
@@ -2081,7 +1725,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;}
       || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
   fi
 done
 
@@ -2170,72 +1814,271 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
+REQUIRE_ERLANG_MIN="5.9.1 (Erlang/OTP R15B01)"
+REQUIRE_ERLANG_MAX="9.0.0 (No Max)"
 
 # Checks for programs.
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+       @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
 else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           rm -rf conftest.one conftest.two conftest.dir
+           echo one > conftest.one
+           echo two > conftest.two
+           mkdir conftest.dir
+           if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+             test -s conftest.one && test -s conftest.two &&
+             test -s conftest.dir/conftest.one &&
+             test -s conftest.dir/conftest.two
+           then
+             ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+             break 3
+           fi
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+
   done
 IFS=$as_save_IFS
 
+rm -rf conftest.one conftest.two conftest.dir
+
 fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
 fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
 
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="gcc"
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+
+if test "x$GCC" = "xyes"; then
+    CFLAGS="$CFLAGS -Wall"
+fi
+
+# Checks Erlang runtime and compiler
+
+# Check whether --with-erlang was given.
+if test "${with_erlang+set}" = set; then :
+  withval=$with_erlang; if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_erlang" = "X"; then
+    extra_erl_path=""
+else
+    extra_erl_path="$with_erlang:$with_erlang/bin:"
+fi
+
+fi
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args.
+set dummy ${ac_tool_prefix}erl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ERL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ERL="$ERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in ${extra_erl_path}$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -2243,19 +2086,63 @@ done
   done
 IFS=$as_save_IFS
 
+  ;;
+esac
+fi
+ERL=$ac_cv_path_ERL
+if test -n "$ERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5
+$as_echo "$ERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
 fi
+if test -z "$ac_cv_path_ERL"; then
+  ac_pt_ERL=$ERL
+  # Extract the first word of "erl", so it can be a program name with args.
+set dummy erl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ac_pt_ERL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_ERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in ${extra_erl_path}$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
 fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+ac_pt_ERL=$ac_cv_path_ac_pt_ERL
+if test -n "$ac_pt_ERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERL" >&5
+$as_echo "$ac_pt_ERL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
-  if test "x$ac_ct_CC" = x; then
-    CC=""
+  if test "x$ac_pt_ERL" = x; then
+    ERL=""
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
@@ -2263,32 +2150,33 @@ yes:)
 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
-    CC=$ac_ct_CC
+    ERL=$ac_pt_ERL
   fi
 else
-  CC="$ac_cv_prog_CC"
+  ERL="$ac_cv_path_ERL"
 fi
 
-if test -z "$CC"; then
-          if test -n "$ac_tool_prefix"; then
-    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}erlc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
+if test "${ac_cv_path_ERLC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+  case $ERLC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in ${extra_erl_path}$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -2296,44 +2184,42 @@ done
   done
 IFS=$as_save_IFS
 
+  ;;
+esac
 fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+ERLC=$ac_cv_path_ERLC
+if test -n "$ERLC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5
+$as_echo "$ERLC" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
-  fi
 fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
+if test -z "$ac_cv_path_ERLC"; then
+  ac_pt_ERLC=$ERLC
+  # Extract the first word of "erlc", so it can be a program name with args.
+set dummy erlc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
+if test "${ac_cv_path_ac_pt_ERLC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+  case $ac_pt_ERLC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in ${extra_erl_path}$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
+    ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -2341,53 +2227,61 @@ done
   done
 IFS=$as_save_IFS
 
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
+  ;;
+esac
 fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC
+if test -n "$ac_pt_ERLC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERLC" >&5
+$as_echo "$ac_pt_ERLC" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
-
+  if test "x$ac_pt_ERLC" = x; then
+    ERLC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    ERLC=$ac_pt_ERLC
+  fi
+else
+  ERLC="$ac_cv_path_ERLC"
 fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl.exe
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+
+
+if test -n "$ERL"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erl" >&5
+$as_echo_n "checking for erl... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5
+$as_echo "$ERL" >&6; }
+else
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args.
+set dummy ${ac_tool_prefix}erl; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
+if test "${ac_cv_path_ERL+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  case $ERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ERL="$ERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -2395,43 +2289,42 @@ done
   done
 IFS=$as_save_IFS
 
+  ;;
+esac
 fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+ERL=$ac_cv_path_ERL
+if test -n "$ERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5
+$as_echo "$ERL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
-    test -n "$CC" && break
-  done
 fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl.exe
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
+if test -z "$ac_cv_path_ERL"; then
+  ac_pt_ERL=$ERL
+  # Extract the first word of "erl", so it can be a program name with args.
+set dummy erl; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
+if test "${ac_cv_path_ac_pt_ERL+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  case $ac_pt_ERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
+    ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -2439,23 +2332,20 @@ done
   done
 IFS=$as_save_IFS
 
+  ;;
+esac
 fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+ac_pt_ERL=$ac_cv_path_ac_pt_ERL
+if test -n "$ac_pt_ERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERL" >&5
+$as_echo "$ac_pt_ERL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
-
-  test -n "$ac_ct_CC" && break
-done
-
-  if test "x$ac_ct_CC" = x; then
-    CC=""
+  if test "x$ac_pt_ERL" = x; then
+    ERL="not found"
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
@@ -2463,555 +2353,29 @@ yes:)
 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
-    CC=$ac_ct_CC
+    ERL=$ac_pt_ERL
   fi
+else
+  ERL="$ac_cv_path_ERL"
 fi
-
 fi
 
+if test "$ERL" = "not found"; then
+    as_fn_error $? "Erlang/OTP interpreter (erl) not found but required" "$LINENO" 5
+fi
 
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
-  { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    sed '10a\
-... rest of stderr output deleted ...
-         10q' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-  fi
-  rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
-  esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link_default") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile.  We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
-       ;;
-    [ab].out )
-       # We found the default executable, but exeext='' is most
-       # certainly right.
-       break;;
-    *.* )
-       if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
-       then :; else
-          ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-       fi
-       # We set ac_cv_exeext here because the later test for it is not
-       # safe: cross compilers may not add the suffix if given an `-o'
-       # argument, so we may need to know it at that point already.
-       # Even if this section looks crufty: it has the advantage of
-       # actually working.
-       break;;
-    * )
-       break;;
-  esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
-  ac_file=''
-fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-         break;;
-    * ) break;;
-  esac
-done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
-  { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }
-  if { ac_try='./conftest$ac_cv_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-       cross_compiling=yes
-    else
-       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
-    fi
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_compile") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
-  for ac_file in conftest.o conftest.obj conftest.*; do
-  test -f "$ac_file" || continue;
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_compiler_gnu=yes
-else
-  ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
-  GCC=yes
-else
-  GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_c_werror_flag=$ac_c_werror_flag
-   ac_c_werror_flag=yes
-   ac_cv_prog_cc_g=no
-   CFLAGS="-g"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-else
-  CFLAGS=""
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  ac_c_werror_flag=$ac_save_c_werror_flag
-        CFLAGS="-g"
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-       -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
-  test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
-set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat >conftest.make <<\_ACEOF
-SHELL = /bin/sh
-all:
-       @echo '@@@%%%=$(MAKE)=@@@%%%'
-_ACEOF
-# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
-case `${MAKE-make} -f conftest.make 2>/dev/null` in
-  *@@@%%%=?*=@@@%%%*)
-    eval ac_cv_prog_make_${ac_make}_set=yes;;
-  *)
-    eval ac_cv_prog_make_${ac_make}_set=no;;
-esac
-rm -f conftest.make
-fi
-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-  SET_MAKE=
+if test -n "$ERLC"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erlc" >&5
+$as_echo_n "checking for erlc... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5
+$as_echo "$ERLC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-  SET_MAKE="MAKE=${MAKE-make}"
-fi
-
-
-if test "x$GCC" = "xyes"; then
-    CFLAGS="$CFLAGS -Wall"
-fi
-
-#locating erlang
-
-# Check whether --with-erlang was given.
-if test "${with_erlang+set}" = set; then :
-  withval=$with_erlang;
-fi
-
-
-   if test -n "$ac_tool_prefix"; then
+    if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}erlc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ERLC+:} false; then :
+if test "${ac_cv_path_ERLC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ERLC in
@@ -3020,8 +2384,7 @@ else
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$with_erlang:$with_erlang/bin:$PATH"
-for as_dir in $as_dummy
+for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
@@ -3055,7 +2418,7 @@ if test -z "$ac_cv_path_ERLC"; then
 set dummy erlc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_ERLC+:} false; then :
+if test "${ac_cv_path_ac_pt_ERLC+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_ERLC in
@@ -3064,8 +2427,7 @@ else
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$with_erlang:$with_erlang/bin:$PATH"
-for as_dir in $as_dummy
+for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
@@ -3092,7 +2454,7 @@ $as_echo "no" >&6; }
 fi
 
   if test "x$ac_pt_ERLC" = x; then
-    ERLC=""
+    ERLC="not found"
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
   ERLC="$ac_cv_path_ERLC"
 fi
 
-   if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args.
-set dummy ${ac_tool_prefix}erl; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ERL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $ERL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ERL="$ERL" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$with_erlang:$with_erlang/bin:$PATH"
-for as_dir in $as_dummy
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
 fi
-ERL=$ac_cv_path_ERL
-if test -n "$ERL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5
-$as_echo "$ERL" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+
+if test "$ERLC" = "not found"; then
+    as_fn_error $? "Erlang/OTP compiler (erlc) not found but required" "$LINENO" 5
 fi
 
 
+# Check whether --enable-erlang-version-check was given.
+if test "${enable_erlang_version_check+set}" = set; then :
+  enableval=$enable_erlang_version_check;
 fi
-if test -z "$ac_cv_path_ERL"; then
-  ac_pt_ERL=$ERL
-  # Extract the first word of "erl", so it can be a program name with args.
-set dummy erl; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_ERL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $ac_pt_ERL in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_dummy="$with_erlang:$with_erlang/bin:$PATH"
-for as_dir in $as_dummy
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
 
-  ;;
-esac
-fi
-ac_pt_ERL=$ac_cv_path_ac_pt_ERL
-if test -n "$ac_pt_ERL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERL" >&5
-$as_echo "$ac_pt_ERL" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
+       case "$enable_erlang_version_check" in
+       yes|'')
+                               { $as_echo "$as_me:${as_lineno-$LINENO}: checking Erlang/OTP version" >&5
+$as_echo_n "checking Erlang/OTP version... " >&6; }
+               cat > conftest.erl <<EOF
+-module(conftest).
+-export([start/0]).
 
-  if test "x$ac_pt_ERL" = x; then
-    ERL=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    ERL=$ac_pt_ERL
-  fi
-else
-  ERL="$ac_cv_path_ERL"
-fi
+start() ->
+    ERTS = erlang:system_info(version),
+    RequiredMin = "$REQUIRE_ERLANG_MIN",
+    RequiredMax = "$REQUIRE_ERLANG_MAX",
+    Status =
+        case {string:tokens(RequiredMin, " "),
+              string:tokens(RequiredMax, " ")} of
+           {[MinStr | _], [MaxStr | _]} ->
+                case check(ERTS, {MinStr, MaxStr}) of
+                    less ->
+                         list_to_binary([ERTS, " found, ", RequiredMin, " required"]);
+                    greater ->
+                         list_to_binary([ERTS, " found, ", RequiredMax, " or earlier required"]);
+                    ok ->
+                        <<"ok">>
+                end;
+           _ ->
+               list_to_binary([ERTS, " found, ", RequiredMin, " required"])
+       end,
+    file:write_file("conftest.out", Status),
+    halt().
+
+check(CurStr, {MinStr, MaxStr}) ->
+    Cur = parse(CurStr),
+    Min = parse(MinStr),
+    Max = parse(MaxStr),
+    case {less_or_equal(Min, Cur), less_or_equal(Cur, Max)} of
+        {false, true} -> less;
+        {true, true} -> ok;
+        {true, false} -> greater
+    end.
 
+parse(Version) ->
+    lists:map(fun(A) -> {Int,[]} = string:to_integer(A), Int end,
+              string:tokens(Version, ".")).
+
+less_or_equal([], []) ->
+    true;
+less_or_equal([Left| Rl], [Right| Rr]) ->
+    case {Left < Right, Left == Right} of
+        {true, _}  ->
+            true;
+        {false, false} ->
+            false;
+        {false, true} ->
+            less_or_equal(Rl, Rr)
+    end.
 
-   if test "z$ERLC" = "z" || test "z$ERL" = "z"; then
-               as_fn_error $? "erlang not found" "$LINENO" 5
-   fi
+EOF
 
+       $ERLC conftest.erl || as_fn_error $? "\"Could not compile Erlang/OTP version check program using '$ERLC'\"" "$LINENO" 5
 
-   cat >>conftest.erl <<_EOF
+       if ! $ERL -s conftest -noshell -o ! -f conftest.out ; then
+          as_fn_error $? "\"Could not run Erlang/OTP version check program using '$ERL'\"" "$LINENO" 5
+       fi
 
--module(conftest).
--author('alexey@sevcom.net').
+       if test "x`cat conftest.out`" != "xok"; then
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+          X="`cat conftest.out`"
+          if test "" == "warn"; then
+             { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $X" >&5
+$as_echo "$as_me: WARNING: $X" >&2;}
+          else
+             { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "$X
+See \`config.log' for more details" "$LINENO" 5 ; }
+          fi
+       else
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+       fi
 
+               ;;
+       no)
+                               { $as_echo "$as_me:${as_lineno-$LINENO}: checking Erlang/OTP version" >&5
+$as_echo_n "checking Erlang/OTP version... " >&6; }
+               cat > conftest.erl <<EOF
+-module(conftest).
 -export([start/0]).
 
 start() ->
-    EIDirS = code:lib_dir("erl_interface") ++ "\n",
-    EILibS =  libpath("erl_interface") ++ "\n",
-    RootDirS = code:root_dir() ++ "\n",
-    file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ RootDirS)),
+    ERTS = erlang:system_info(version),
+    RequiredMin = "$REQUIRE_ERLANG_MIN",
+    RequiredMax = "$REQUIRE_ERLANG_MAX",
+    Status =
+        case {string:tokens(RequiredMin, " "),
+              string:tokens(RequiredMax, " ")} of
+           {[MinStr | _], [MaxStr | _]} ->
+                case check(ERTS, {MinStr, MaxStr}) of
+                    less ->
+                         list_to_binary([ERTS, " found, ", RequiredMin, " required"]);
+                    greater ->
+                         list_to_binary([ERTS, " found, ", RequiredMax, " or earlier required"]);
+                    ok ->
+                        <<"ok">>
+                end;
+           _ ->
+               list_to_binary([ERTS, " found, ", RequiredMin, " required"])
+       end,
+    file:write_file("conftest.out", Status),
     halt().
 
-%% return physical architecture based on OS/Processor
-archname() ->
-    ArchStr = erlang:system_info(system_architecture),
-    case os:type() of
-       {win32, _} -> "windows";
-       {unix,UnixName} ->
-           Specs = string:tokens(ArchStr,"-"),
-           Cpu = case lists:nth(2,Specs) of
-                     "pc" -> "x86";
-                     _ -> hd(Specs)
-                 end,
-           atom_to_list(UnixName) ++ "-" ++ Cpu;
-       _ -> "generic"
+check(CurStr, {MinStr, MaxStr}) ->
+    Cur = parse(CurStr),
+    Min = parse(MinStr),
+    Max = parse(MaxStr),
+    case {less_or_equal(Min, Cur), less_or_equal(Cur, Max)} of
+        {false, true} -> less;
+        {true, true} -> ok;
+        {true, false} -> greater
     end.
 
-%% Return arch-based library path or a default value if this directory
-%% does not exist
-libpath(App) ->
-    PrivDir    = code:priv_dir(App),
-    ArchDir    = archname(),
-    LibArchDir = filename:join([PrivDir,"lib",ArchDir]),
-    case file:list_dir(LibArchDir) of
-       %% Arch lib dir exists: We use it
-       {ok, _List}  -> LibArchDir;
-       %% Arch lib dir does not exist: Return the default value
-       %% ({error, enoent}):
-       _Error -> code:lib_dir("erl_interface") ++ "/lib"
+parse(Version) ->
+    lists:map(fun(A) -> {Int,[]} = string:to_integer(A), Int end,
+              string:tokens(Version, ".")).
+
+less_or_equal([], []) ->
+    true;
+less_or_equal([Left| Rl], [Right| Rr]) ->
+    case {Left < Right, Left == Right} of
+        {true, _}  ->
+            true;
+        {false, false} ->
+            false;
+        {false, true} ->
+            less_or_equal(Rl, Rr)
     end.
 
-_EOF
-
-   if ! $ERLC conftest.erl; then
-          as_fn_error $? "could not compile sample program" "$LINENO" 5
-   fi
+EOF
 
-   if ! $ERL -s conftest -noshell; then
-       as_fn_error $? "could not run sample program" "$LINENO" 5
-   fi
+       $ERLC conftest.erl || as_fn_error $? "\"Could not compile Erlang/OTP version check program using '$ERLC'\"" "$LINENO" 5
 
-   if ! test -f conftest.out; then
-       as_fn_error $? "erlang program was not properly executed, (conftest.out was not produced)" "$LINENO" 5
-   fi
+       if ! $ERL -s conftest -noshell -o ! -f conftest.out ; then
+          as_fn_error $? "\"Could not run Erlang/OTP version check program using '$ERL'\"" "$LINENO" 5
+       fi
 
-   # First line
-   ERLANG_EI_DIR=`cat conftest.out | head -n 1`
-   # Second line
-   ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
-   # End line
-   ERLANG_DIR=`cat conftest.out | tail -n 1`
+       if test "x`cat conftest.out`" != "xok"; then
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+          X="`cat conftest.out`"
+          if test "warn" == "warn"; then
+             { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $X" >&5
+$as_echo "$as_me: WARNING: $X" >&2;}
+          else
+             { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "$X
+See \`config.log' for more details" "$LINENO" 5 ; }
+          fi
+       else
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+       fi
 
-   ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include"
-   ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei"
+               ;;
+esac
 
+# Checks and sets ERLANG_ROOT_DIR and ERLANG_LIB_DIR variable
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP root directory" >&5
+$as_echo_n "checking for Erlang/OTP root directory... " >&6; }
+if test "${ac_cv_erlang_root_dir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
+start() ->
+           RootDir = code:root_dir(),
+           file:write_file("conftest.out", RootDir),
+           ReturnValue = 0,
+           halt(ReturnValue)
+.
 
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_root_dir=`cat conftest.out`
+        rm -f conftest.out
+else
+  rm -f conftest.out
+        { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
 
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-#locating iconv
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_root_dir" >&5
+$as_echo "$ac_cv_erlang_root_dir" >&6; }
+ERLANG_ROOT_DIR=$ac_cv_erlang_root_dir
 
 
+# AC_ERLANG_SUBST_LIB_DIR
 
-# Check whether --with-libiconv-prefix was given.
-if test "${with_libiconv_prefix+set}" = set; then :
-  withval=$with_libiconv_prefix;
-    for dir in `echo "$withval" | tr : ' '`; do
-      if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
-      if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
-      if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi
-    done
+#locating escript
+# Extract the first word of "escript", so it can be a program name with args.
+set dummy escript; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ESCRIPT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ESCRIPT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ESCRIPT="$ESCRIPT" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $ERLANG_ROOT_DIR/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ESCRIPT="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
+  ;;
+esac
+fi
+ESCRIPT=$ac_cv_path_ESCRIPT
+if test -n "$ESCRIPT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ESCRIPT" >&5
+$as_echo "$ESCRIPT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5
-$as_echo_n "checking for iconv... " >&6; }
-if ${am_cv_func_iconv+:} false; then :
+
+#locating make
+# Extract the first word of "make", so it can be a program name with args.
+set dummy make; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_MAKE+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
+  if test -n "$MAKE"; then
+  ac_cv_prog_MAKE="$MAKE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_MAKE="make"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-    am_cv_func_iconv="no, consider installing GNU libiconv"
-    am_cv_lib_iconv=no
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <iconv.h>
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
-       iconv(cd,NULL,NULL,NULL,NULL);
-       iconv_close(cd);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  am_cv_func_iconv=yes
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-    if test "$am_cv_func_iconv" != yes; then
-      am_save_LIBS="$LIBS"
-      LIBS="$LIBS -liconv"
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <iconv.h>
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
-         iconv(cd,NULL,NULL,NULL,NULL);
-         iconv_close(cd);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  am_cv_lib_iconv=yes
-        am_cv_func_iconv=yes
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-      LIBS="$am_save_LIBS"
-    fi
-           if test "$am_cv_func_iconv" != yes; then
-      am_save_LIBS="$LIBS"
-         am_save_CFLAGS="$CFLAGS"
-         am_save_LDFLAGS="$LDFLAGS"
-      LIBS="$LIBS -liconv"
-         LDFLAGS="$LDFLAGS -L/usr/local/lib"
-         CFLAGS="$CFLAGS -I/usr/local/include"
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <iconv.h>
-int
-main ()
-{
-iconv_t cd = iconv_open("","");
-         iconv(cd,NULL,NULL,NULL,NULL);
-         iconv_close(cd);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  am_cv_lib_iconv=yes
-        am_cv_func_iconv=yes
-               CPPFLAGS="$CPPFLAGS -I/usr/local/include"
+fi
+MAKE=$ac_cv_prog_MAKE
+if test -n "$MAKE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5
+$as_echo "$MAKE" >&6; }
 else
-  LDFLAGS="$am_save_LDFLAGS"
-               CFLAGS="$am_save_CFLAGS"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-      LIBS="$am_save_LIBS"
-    fi
 
 
+
+if test "x$ESCRIPT" = "x"; then
+   as_fn_error $? "'escript' was not found" "$LINENO" 5
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5
-$as_echo "$am_cv_func_iconv" >&6; }
-  if test "$am_cv_func_iconv" = yes; then
 
-$as_echo "#define HAVE_ICONV 1" >>confdefs.h
+if test "x$MAKE" = "x"; then
+   as_fn_error $? "'make' was not found" "$LINENO" 5
+fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5
-$as_echo_n "checking for iconv declaration... " >&6; }
-    if ${am_cv_proto_iconv+:} false; then :
-  $as_echo_n "(cached) " >&6
+# Change default prefix
+
+
+# Check whether --enable-hipe was given.
+if test "${enable_hipe+set}" = set; then :
+  enableval=$enable_hipe; case "${enableval}" in
+  yes) hipe=true ;;
+  no)  hipe=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-hipe" "$LINENO" 5  ;;
+esac
 else
+  hipe=false
+fi
 
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-#include <stdlib.h>
-#include <iconv.h>
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
+# Check whether --enable-roster_gateway_workaround was given.
+if test "${enable_roster_gateway_workaround+set}" = set; then :
+  enableval=$enable_roster_gateway_workaround; case "${enableval}" in
+  yes) roster_gateway_workaround=true ;;
+  no)  roster_gateway_workaround=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-roster-gateway-workaround" "$LINENO" 5  ;;
+esac
+else
+  roster_gateway_workaround=false
+fi
 
-int
-main ()
-{
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  am_cv_proto_iconv_arg1=""
+# Check whether --enable-transient_supervisors was given.
+if test "${enable_transient_supervisors+set}" = set; then :
+  enableval=$enable_transient_supervisors; case "${enableval}" in
+  yes) transient_supervisors=true ;;
+  no)  transient_supervisors=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-transient_supervisors" "$LINENO" 5  ;;
+esac
 else
-  am_cv_proto_iconv_arg1="const"
+  transient_supervisors=false
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"
+
+
+# Check whether --enable-full_xml was given.
+if test "${enable_full_xml+set}" = set; then :
+  enableval=$enable_full_xml; case "${enableval}" in
+  yes) full_xml=true ;;
+  no)  full_xml=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-full-xml" "$LINENO" 5  ;;
+esac
+else
+  full_xml=false
 fi
 
-    am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:-
-         }$am_cv_proto_iconv" >&5
-$as_echo "${ac_t:-
-         }$am_cv_proto_iconv" >&6; }
 
-cat >>confdefs.h <<_ACEOF
-#define ICONV_CONST $am_cv_proto_iconv_arg1
-_ACEOF
+# Check whether --enable-mssql was given.
+if test "${enable_mssql+set}" = set; then :
+  enableval=$enable_mssql; case "${enableval}" in
+  yes) db_type=mssql ;;
+  no)  db_type=generic ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-mssql" "$LINENO" 5  ;;
+esac
+else
+  db_type=generic
+fi
 
-  fi
-  LIBICONV=
-  if test "$am_cv_lib_iconv" = yes; then
-    LIBICONV="-liconv"
-  fi
+
+# Check whether --enable-tools was given.
+if test "${enable_tools+set}" = set; then :
+  enableval=$enable_tools; case "${enableval}" in
+  yes) tools=true ;;
+  no)  tools=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-tools" "$LINENO" 5  ;;
+esac
+else
+  tools=false
+fi
 
 
-#locating libexpat
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
+# Check whether --enable-all was given.
+if test "${enable_all+set}" = set; then :
+  enableval=$enable_all; case "${enableval}" in
+  yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true stun=true json=true iconv=true debug=true http=true ;;
+  no) nif=false odbc=false mysql=false pgsql=false pam=false zlib=false stun=false json=false iconv=false debug=false http=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-all" "$LINENO" 5  ;;
+esac
+fi
+
+
+# Check whether --enable-nif was given.
+if test "${enable_nif+set}" = set; then :
+  enableval=$enable_nif; case "${enableval}" in
+  yes) nif=true ;;
+  no)  nif=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-nif" "$LINENO" 5  ;;
+esac
 else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+  if test "x$nif" = "x"; then nif=false; fi
+fi
+
 
+# Check whether --enable-odbc was given.
+if test "${enable_odbc+set}" = set; then :
+  enableval=$enable_odbc; case "${enableval}" in
+  yes) odbc=true ;;
+  no)  odbc=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-odbc" "$LINENO" 5  ;;
+esac
 else
-  # Broken: fails on valid input.
-continue
+  if test "x$odbc" = "x"; then odbc=false; fi
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
+
+# Check whether --enable-mysql was given.
+if test "${enable_mysql+set}" = set; then :
+  enableval=$enable_mysql; case "${enableval}" in
+  yes) mysql=true ;;
+  no)  mysql=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-mysql" "$LINENO" 5  ;;
+esac
 else
-  # Passes both tests.
-ac_preproc_ok=:
-break
+  if test "x$mysql" = "x"; then mysql=false; fi
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
+
+# Check whether --enable-pgsql was given.
+if test "${enable_pgsql+set}" = set; then :
+  enableval=$enable_pgsql; case "${enableval}" in
+  yes) pgsql=true ;;
+  no)  pgsql=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-pgsql" "$LINENO" 5  ;;
+esac
+else
+  if test "x$pgsql" = "x"; then pgsql=false; fi
 fi
 
-    done
-    ac_cv_prog_CPP=$CPP
 
+# Check whether --enable-pam was given.
+if test "${enable_pam+set}" = set; then :
+  enableval=$enable_pam; case "${enableval}" in
+  yes) pam=true ;;
+  no)  pam=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-pam" "$LINENO" 5  ;;
+esac
+else
+  if test "x$pam" = "x"; then pam=false; fi
 fi
-  CPP=$ac_cv_prog_CPP
+
+
+# Check whether --enable-zlib was given.
+if test "${enable_zlib+set}" = set; then :
+  enableval=$enable_zlib; case "${enableval}" in
+  yes) zlib=true ;;
+  no)  zlib=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-zlib" "$LINENO" 5  ;;
+esac
 else
-  ac_cv_prog_CPP=$CPP
+  if test "x$zlib" = "x"; then zlib=true; fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-                    Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
 
+
+# Check whether --enable-stun was given.
+if test "${enable_stun+set}" = set; then :
+  enableval=$enable_stun; case "${enableval}" in
+  yes) stun=true ;;
+  no)  stun=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-stun" "$LINENO" 5  ;;
+esac
 else
-  # Broken: fails on valid input.
-continue
+  if test "x$stun" = "x"; then stun=false; fi
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
+
+# Check whether --enable-json was given.
+if test "${enable_json+set}" = set; then :
+  enableval=$enable_json; case "${enableval}" in
+  yes) json=true ;;
+  no)  json=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-json" "$LINENO" 5  ;;
+esac
 else
-  # Passes both tests.
-ac_preproc_ok=:
-break
+  if test "x$json" = "x"; then json=false; fi
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
 
+# Check whether --enable-iconv was given.
+if test "${enable_iconv+set}" = set; then :
+  enableval=$enable_iconv; case "${enableval}" in
+  yes) iconv=true ;;
+  no)  iconv=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-iconv" "$LINENO" 5  ;;
+esac
 else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+  if test "x$iconv" = "x"; then iconv=true; fi
 fi
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; case "${enableval}" in
+  yes) debug=true ;;
+  no)  debug=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-debug" "$LINENO" 5  ;;
+esac
+else
+  if test "x$debug" = "x"; then debug=true; fi
+fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
+# Check whether --enable-http was given.
+if test "${enable_http+set}" = set; then :
+  enableval=$enable_http; case "${enableval}" in
+  yes) http=true ;;
+  no)  http=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-http" "$LINENO" 5  ;;
+esac
 else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_GREP=$GREP
-fi
-
+  if test "x$http" = "x"; then http=false; fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     if test -z "$EGREP"; then
-  ac_path_EGREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+# Check whether --enable-lager was given.
+if test "${enable_lager+set}" = set; then :
+  enableval=$enable_lager; case "${enableval}" in
+  yes) lager=true ;;
+  no)  lager=false ;;
+  *) as_fn_error $? "bad value ${enableval} for --enable-lager" "$LINENO" 5  ;;
 esac
-
-      $ac_path_EGREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
 else
-  ac_cv_path_EGREP=$EGREP
+  if test "x$lager" = "x"; then lager=true; fi
 fi
 
-   fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
+ac_config_files="$ac_config_files Makefile vars.config src/ejabberd.app.src"
 
-int
-main ()
-{
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
+ENABLEUSER=""
+# Check whether --enable-user was given.
+if test "${enable_user+set}" = set; then :
+  enableval=$enable_user; case "${enableval}" in
+     yes) ENABLEUSER=`whoami` ;;
+     no) ENABLEUSER="" ;;
+     *) ENABLEUSER=$enableval
+   esac
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
+if test "$ENABLEUSER" != ""; then
+  echo "allow this system user to start ejabberd: $ENABLEUSER"
+  INSTALLUSER=$ENABLEUSER
 
 fi
 
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'sasl' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'sasl' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_sasl+set}" = set; then :
+  $as_echo_n "(cached) " >&6
 else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-                  (('a' <= (c) && (c) <= 'i') \
-                    || ('j' <= (c) && (c) <= 'r') \
-                    || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-       || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+start() ->
+           ReturnValue = case code:lib_dir("sasl") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_sasl=`cat conftest.out`
+        rm -f conftest.out
 else
-  ac_cv_header_stdc=no
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_sasl="not found"
+            rm -f conftest.out
+        fi
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-                 inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-# Check whether --with-expat was given.
-if test "${with_expat+set}" = set; then :
-  withval=$with_expat;
 fi
-
-
-  EXPAT_CFLAGS=
-  EXPAT_LIBS=
-       if test x"$with_expat" != x; then
-               EXPAT_CFLAGS="-I$with_expat/include"
-               EXPAT_LIBS="-L$with_expat/lib"
-       fi
-
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML_ParserCreate in -lexpat" >&5
-$as_echo_n "checking for XML_ParserCreate in -lexpat... " >&6; }
-if ${ac_cv_lib_expat_XML_ParserCreate+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_sasl" >&5
+$as_echo "$ac_cv_erlang_lib_dir_sasl" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'sasl' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'sasl' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_sasl+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lexpat "$EXPAT_LIBS" $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XML_ParserCreate ();
-int
-main ()
-{
-return XML_ParserCreate ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_expat_XML_ParserCreate=yes
+  if test "$ac_cv_erlang_lib_dir_sasl" = "not found"; then :
+  ac_cv_erlang_lib_ver_sasl="not found"
 else
-  ac_cv_lib_expat_XML_ParserCreate=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+  ac_cv_erlang_lib_ver_sasl=`$as_echo "$ac_cv_erlang_lib_dir_sasl" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_ParserCreate" >&5
-$as_echo "$ac_cv_lib_expat_XML_ParserCreate" >&6; }
-if test "x$ac_cv_lib_expat_XML_ParserCreate" = xyes; then :
-   EXPAT_LIBS="$EXPAT_LIBS -lexpat"
-                      expat_found=yes
-else
-   expat_found=no
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_sasl" >&5
+$as_echo "$ac_cv_erlang_lib_ver_sasl" >&6; }
+ERLANG_LIB_DIR_sasl=$ac_cv_erlang_lib_dir_sasl
 
-       if test $expat_found = no; then
-               as_fn_error $? "Could not find development files of Expat library" "$LINENO" 5
-       fi
-       expat_save_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS $EXPAT_CFLAGS"
-       expat_save_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $EXPAT_CFLAGS"
-       for ac_header in expat.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default"
-if test "x$ac_cv_header_expat_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_EXPAT_H 1
-_ACEOF
+ERLANG_LIB_VER_sasl=$ac_cv_erlang_lib_ver_sasl
 
-else
-  expat_found=no
+if test "$ac_cv_erlang_lib_dir_sasl" = "not found"; then :
+  as_fn_error $? "Erlang application 'sasl' was not found" "$LINENO" 5
 fi
 
-done
-
-       if test $expat_found = no; then
-               as_fn_error $? "Could not find expat.h" "$LINENO" 5
-       fi
-       CFLAGS="$expat_save_CFLAGS"
-       CPPFLAGS="$expat_save_CPPFLAGS"
-
-
-
-
-
-# Checks for typedefs, structures, and compiler characteristics.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
-$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
-if ${ac_cv_c_const+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'crypto' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'crypto' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_crypto+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-/* FIXME: Include the comments suggested by Paul. */
-#ifndef __cplusplus
-  /* Ultrix mips cc rejects this.  */
-  typedef int charset[2];
-  const charset cs;
-  /* SunOS 4.1.1 cc rejects this.  */
-  char const *const *pcpcc;
-  char **ppc;
-  /* NEC SVR4.0.2 mips cc rejects this.  */
-  struct point {int x, y;};
-  static struct point const zero = {0,0};
-  /* AIX XL C 1.02.0.0 rejects this.
-     It does not let you subtract one const X* pointer from another in
-     an arm of an if-expression whose if-part is not a constant
-     expression */
-  const char *g = "string";
-  pcpcc = &g + (g ? g-g : 0);
-  /* HPUX 7.0 cc rejects these. */
-  ++pcpcc;
-  ppc = (char**) pcpcc;
-  pcpcc = (char const *const *) ppc;
-  { /* SCO 3.2v4 cc rejects this.  */
-    char *t;
-    char const *s = 0 ? (char *) 0 : (char const *) 0;
-
-    *t++ = 0;
-    if (s) return 0;
-  }
-  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
-    int x[] = {25, 17};
-    const int *foo = &x[0];
-    ++foo;
-  }
-  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
-    typedef const int *iptr;
-    iptr p = 0;
-    ++p;
-  }
-  { /* AIX XL C 1.02.0.0 rejects this saying
-       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-    struct s { int j; const int *ap[3]; };
-    struct s *b; b->j = 5;
-  }
-  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
-    const int foo = 10;
-    if (!foo) return 0;
-  }
-  return !cs[0] && !zero.x;
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_c_const=yes
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-  ac_cv_c_const=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
-$as_echo "$ac_cv_c_const" >&6; }
-if test $ac_cv_c_const = no; then
-
-$as_echo "#define const /**/" >>confdefs.h
-
-fi
-
-
-# Check Erlang headers are installed
-#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
-
-# Change default prefix
-
-
-# Checks for library functions.
-for ac_header in stdlib.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_stdlib_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_STDLIB_H 1
-_ACEOF
-
-fi
-
-done
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
-$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
-if ${ac_cv_func_malloc_0_nonnull+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "$cross_compiling" = yes; then :
-  ac_cv_func_malloc_0_nonnull=no
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#if defined STDC_HEADERS || defined HAVE_STDLIB_H
-# include <stdlib.h>
-#else
-char *malloc ();
-#endif
+start() ->
+           ReturnValue = case code:lib_dir("crypto") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
-int
-main ()
-{
-return ! malloc (0);
-  ;
-  return 0;
-}
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  ac_cv_func_malloc_0_nonnull=yes
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_crypto=`cat conftest.out`
+        rm -f conftest.out
 else
-  ac_cv_func_malloc_0_nonnull=no
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_crypto="not found"
+            rm -f conftest.out
+        fi
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
-$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
-if test $ac_cv_func_malloc_0_nonnull = yes; then :
-
-$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
-
-else
-  $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
-
-   case " $LIBOBJS " in
-  *" malloc.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
- ;;
-esac
-
-
-$as_echo "#define malloc rpl_malloc" >>confdefs.h
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_crypto" >&5
+$as_echo "$ac_cv_erlang_lib_dir_crypto" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'crypto' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'crypto' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_crypto+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
+  if test "$ac_cv_erlang_lib_dir_crypto" = "not found"; then :
+  ac_cv_erlang_lib_ver_crypto="not found"
 else
-  ac_cv_header_stdc=no
+  ac_cv_erlang_lib_ver_crypto=`$as_echo "$ac_cv_erlang_lib_dir_crypto" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-rm -f conftest*
-
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_crypto" >&5
+$as_echo "$ac_cv_erlang_lib_ver_crypto" >&6; }
+ERLANG_LIB_DIR_crypto=$ac_cv_erlang_lib_dir_crypto
 
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
+ERLANG_LIB_VER_crypto=$ac_cv_erlang_lib_ver_crypto
 
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
+if test "$ac_cv_erlang_lib_dir_crypto" = "not found"; then :
+  as_fn_error $? "Erlang application 'crypto' was not found" "$LINENO" 5
 fi
-rm -f conftest*
 
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'public_key' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'public_key' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_public_key+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-                  (('a' <= (c) && (c) <= 'i') \
-                    || ('j' <= (c) && (c) <= 'r') \
-                    || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-       || toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+start() ->
+           ReturnValue = case code:lib_dir("public_key") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_public_key=`cat conftest.out`
+        rm -f conftest.out
 else
-  ac_cv_header_stdc=no
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_public_key="not found"
+            rm -f conftest.out
+        fi
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-
-
-
-mod_irc=
-make_mod_irc=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_irc" >&5
-$as_echo_n "checking whether build mod_irc... " >&6; }
-# Check whether --enable-mod_irc was given.
-if test "${enable_mod_irc+set}" = set; then :
-  enableval=$enable_mod_irc; mr_enable_mod_irc="$enableval"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_public_key" >&5
+$as_echo "$ac_cv_erlang_lib_dir_public_key" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'public_key' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'public_key' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_public_key+set}" = set; then :
+  $as_echo_n "(cached) " >&6
 else
-  mr_enable_mod_irc=yes
-fi
-
-if test "$mr_enable_mod_irc" = "yes"; then
-mod_irc=mod_irc
-make_mod_irc=mod_irc/Makefile
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_irc" >&5
-$as_echo "$mr_enable_mod_irc" >&6; }
-
-
-
-
-
-mod_muc=
-make_mod_muc=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_muc" >&5
-$as_echo_n "checking whether build mod_muc... " >&6; }
-# Check whether --enable-mod_muc was given.
-if test "${enable_mod_muc+set}" = set; then :
-  enableval=$enable_mod_muc; mr_enable_mod_muc="$enableval"
+  if test "$ac_cv_erlang_lib_dir_public_key" = "not found"; then :
+  ac_cv_erlang_lib_ver_public_key="not found"
 else
-  mr_enable_mod_muc=yes
+  ac_cv_erlang_lib_ver_public_key=`$as_echo "$ac_cv_erlang_lib_dir_public_key" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-
-if test "$mr_enable_mod_muc" = "yes"; then
-mod_muc=mod_muc
-make_mod_muc=mod_muc/Makefile
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_muc" >&5
-$as_echo "$mr_enable_mod_muc" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_public_key" >&5
+$as_echo "$ac_cv_erlang_lib_ver_public_key" >&6; }
+ERLANG_LIB_DIR_public_key=$ac_cv_erlang_lib_dir_public_key
 
+ERLANG_LIB_VER_public_key=$ac_cv_erlang_lib_ver_public_key
 
-
-
-
-mod_proxy65=
-make_mod_proxy65=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_proxy65" >&5
-$as_echo_n "checking whether build mod_proxy65... " >&6; }
-# Check whether --enable-mod_proxy65 was given.
-if test "${enable_mod_proxy65+set}" = set; then :
-  enableval=$enable_mod_proxy65; mr_enable_mod_proxy65="$enableval"
-else
-  mr_enable_mod_proxy65=yes
+if test "$ac_cv_erlang_lib_dir_public_key" = "not found"; then :
+  as_fn_error $? "Erlang application 'public_key' was not found" "$LINENO" 5
 fi
 
-if test "$mr_enable_mod_proxy65" = "yes"; then
-mod_proxy65=mod_proxy65
-make_mod_proxy65=mod_proxy65/Makefile
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_proxy65" >&5
-$as_echo "$mr_enable_mod_proxy65" >&6; }
-
-
-
-
-
-mod_pubsub=
-make_mod_pubsub=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_pubsub" >&5
-$as_echo_n "checking whether build mod_pubsub... " >&6; }
-# Check whether --enable-mod_pubsub was given.
-if test "${enable_mod_pubsub+set}" = set; then :
-  enableval=$enable_mod_pubsub; mr_enable_mod_pubsub="$enableval"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'ssl' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'ssl' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_ssl+set}" = set; then :
+  $as_echo_n "(cached) " >&6
 else
-  mr_enable_mod_pubsub=yes
-fi
-
-if test "$mr_enable_mod_pubsub" = "yes"; then
-mod_pubsub=mod_pubsub
-make_mod_pubsub=mod_pubsub/Makefile
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_pubsub" >&5
-$as_echo "$mr_enable_mod_pubsub" >&6; }
-
-
-
-
-
-eldap=
-make_eldap=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build eldap" >&5
-$as_echo_n "checking whether build eldap... " >&6; }
-# Check whether --enable-eldap was given.
-if test "${enable_eldap+set}" = set; then :
-  enableval=$enable_eldap; mr_enable_eldap="$enableval"
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-  mr_enable_eldap=yes
-fi
-
-if test "$mr_enable_eldap" = "yes"; then
-eldap=eldap
-make_eldap=eldap/Makefile
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_eldap" >&5
-$as_echo "$mr_enable_eldap" >&6; }
-
-
-
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
+start() ->
+           ReturnValue = case code:lib_dir("ssl") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
-odbc=
-make_odbc=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build odbc" >&5
-$as_echo_n "checking whether build odbc... " >&6; }
-# Check whether --enable-odbc was given.
-if test "${enable_odbc+set}" = set; then :
-  enableval=$enable_odbc; mr_enable_odbc="$enableval"
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_ssl=`cat conftest.out`
+        rm -f conftest.out
 else
-  mr_enable_odbc=no
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_ssl="not found"
+            rm -f conftest.out
+        fi
 fi
-
-if test "$mr_enable_odbc" = "yes"; then
-odbc=odbc
-make_odbc=odbc/Makefile
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_odbc" >&5
-$as_echo "$mr_enable_odbc" >&6; }
-
 
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-
-
-tls=
-make_tls=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build tls" >&5
-$as_echo_n "checking whether build tls... " >&6; }
-# Check whether --enable-tls was given.
-if test "${enable_tls+set}" = set; then :
-  enableval=$enable_tls; mr_enable_tls="$enableval"
-else
-  mr_enable_tls=yes
-fi
-
-if test "$mr_enable_tls" = "yes"; then
-tls=tls
-make_tls=tls/Makefile
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_tls" >&5
-$as_echo "$mr_enable_tls" >&6; }
-
-
-
-
-
-web=
-make_web=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build web" >&5
-$as_echo_n "checking whether build web... " >&6; }
-# Check whether --enable-web was given.
-if test "${enable_web+set}" = set; then :
-  enableval=$enable_web; mr_enable_web="$enableval"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_ssl" >&5
+$as_echo "$ac_cv_erlang_lib_dir_ssl" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'ssl' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'ssl' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_ssl+set}" = set; then :
+  $as_echo_n "(cached) " >&6
 else
-  mr_enable_web=yes
-fi
-
-if test "$mr_enable_web" = "yes"; then
-web=web
-make_web=web/Makefile
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_web" >&5
-$as_echo "$mr_enable_web" >&6; }
-
-
-
-
-
-
-ejabberd_zlib=
-make_ejabberd_zlib=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build ejabberd_zlib" >&5
-$as_echo_n "checking whether build ejabberd_zlib... " >&6; }
-# Check whether --enable-ejabberd_zlib was given.
-if test "${enable_ejabberd_zlib+set}" = set; then :
-  enableval=$enable_ejabberd_zlib; mr_enable_ejabberd_zlib="$enableval"
+  if test "$ac_cv_erlang_lib_dir_ssl" = "not found"; then :
+  ac_cv_erlang_lib_ver_ssl="not found"
 else
-  mr_enable_ejabberd_zlib=yes
+  ac_cv_erlang_lib_ver_ssl=`$as_echo "$ac_cv_erlang_lib_dir_ssl" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-
-if test "$mr_enable_ejabberd_zlib" = "yes"; then
-ejabberd_zlib=ejabberd_zlib
-make_ejabberd_zlib=ejabberd_zlib/Makefile
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_ejabberd_zlib" >&5
-$as_echo "$mr_enable_ejabberd_zlib" >&6; }
-
-
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_ssl" >&5
+$as_echo "$ac_cv_erlang_lib_ver_ssl" >&6; }
+ERLANG_LIB_DIR_ssl=$ac_cv_erlang_lib_dir_ssl
 
-#locating zlib
+ERLANG_LIB_VER_ssl=$ac_cv_erlang_lib_ver_ssl
 
-# Check whether --with-zlib was given.
-if test "${with_zlib+set}" = set; then :
-  withval=$with_zlib;
+if test "$ac_cv_erlang_lib_dir_ssl" = "not found"; then :
+  as_fn_error $? "Erlang application 'ssl' was not found" "$LINENO" 5
 fi
 
-
-if test x"$ejabberd_zlib" != x; then
-  ZLIB_CFLAGS=
-  ZLIB_LIBS=
-       if test x"$with_zlib" != x; then
-               ZLIB_CFLAGS="-I$with_zlib/include"
-               ZLIB_LIBS="-L$with_zlib/lib"
-       fi
-
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzgets in -lz" >&5
-$as_echo_n "checking for gzgets in -lz... " >&6; }
-if ${ac_cv_lib_z_gzgets+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'mnesia' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'mnesia' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_mnesia+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lz "$ZLIB_LIBS" $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gzgets ();
-int
-main ()
-{
-return gzgets ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_z_gzgets=yes
-else
-  ac_cv_lib_z_gzgets=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzgets" >&5
-$as_echo "$ac_cv_lib_z_gzgets" >&6; }
-if test "x$ac_cv_lib_z_gzgets" = xyes; then :
-   ZLIB_LIBS="$ZLIB_LIBS -lz"
-                      zlib_found=yes
-else
-   zlib_found=no
-fi
-
-       if test $zlib_found = no; then
-               as_fn_error $? "Could not find development files of zlib library. Install them or disable \`ejabberd_zlib' with: --disable-ejabberd_zlib" "$LINENO" 5
-       fi
-       zlib_save_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS $ZLIB_CFLAGS"
-       zlib_save_CPPFLAGS="$CFLAGS"
-       CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS"
-       for ac_header in zlib.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_zlib_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_ZLIB_H 1
-_ACEOF
-
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-  zlib_found=no
-fi
-
-done
-
-       if test $zlib_found = no; then
-               as_fn_error $? "Could not find zlib.h. Install it or disable \`ejabberd_zlib' with: --disable-ejabberd_zlib" "$LINENO" 5
-       fi
-       CFLAGS="$zlib_save_CFLAGS"
-       CPPFLAGS="$zlib_save_CPPFLAGS"
-
-
-
-fi
-
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
+start() ->
+           ReturnValue = case code:lib_dir("mnesia") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
-pam=
-make_pam=
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build pam" >&5
-$as_echo_n "checking whether build pam... " >&6; }
-# Check whether --enable-pam was given.
-if test "${enable_pam+set}" = set; then :
-  enableval=$enable_pam; mr_enable_pam="$enableval"
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_mnesia=`cat conftest.out`
+        rm -f conftest.out
 else
-  mr_enable_pam=no
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_mnesia="not found"
+            rm -f conftest.out
+        fi
 fi
-
-if test "$mr_enable_pam" = "yes"; then
-pam=pam
-make_pam=pam/Makefile
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_pam" >&5
-$as_echo "$mr_enable_pam" >&6; }
-
 
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-
-#locating PAM
-
-# Check whether --with-pam was given.
-if test "${with_pam+set}" = set; then :
-  withval=$with_pam;
 fi
-
-if test x"$pam" != x; then
-  PAM_CFLAGS=
-  PAM_LIBS=
-       if test x"$with_pam" != x; then
-               PAM_CFLAGS="-I$with_pam/include"
-               PAM_LIBS="-L$with_pam/lib"
-       fi
-
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5
-$as_echo_n "checking for pam_start in -lpam... " >&6; }
-if ${ac_cv_lib_pam_pam_start+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_mnesia" >&5
+$as_echo "$ac_cv_erlang_lib_dir_mnesia" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'mnesia' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'mnesia' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_mnesia+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpam "$PAM_LIBS" $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pam_start ();
-int
-main ()
-{
-return pam_start ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_pam_pam_start=yes
-else
-  ac_cv_lib_pam_pam_start=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5
-$as_echo "$ac_cv_lib_pam_pam_start" >&6; }
-if test "x$ac_cv_lib_pam_pam_start" = xyes; then :
-   PAM_LIBS="$PAM_LIBS -lpam"
-                      pam_found=yes
+  if test "$ac_cv_erlang_lib_dir_mnesia" = "not found"; then :
+  ac_cv_erlang_lib_ver_mnesia="not found"
 else
-   pam_found=no
+  ac_cv_erlang_lib_ver_mnesia=`$as_echo "$ac_cv_erlang_lib_dir_mnesia" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-
-       if test $pam_found = no; then
-               as_fn_error $? "Could not find development files of PAM library. Install them or disable \`pam' with: --disable-pam" "$LINENO" 5
-       fi
-       pam_save_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS $PAM_CFLAGS"
-       pam_save_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $PAM_CFLAGS"
-       for ac_header in security/pam_appl.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default"
-if test "x$ac_cv_header_security_pam_appl_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_SECURITY_PAM_APPL_H 1
-_ACEOF
-
-else
-  pam_found=no
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_mnesia" >&5
+$as_echo "$ac_cv_erlang_lib_ver_mnesia" >&6; }
+ERLANG_LIB_DIR_mnesia=$ac_cv_erlang_lib_dir_mnesia
 
-done
-
-       if test $pam_found = no; then
-               as_fn_error $? "Could not find security/pam_appl.h. Install it or disable \`pam' with: --disable-pam" "$LINENO" 5
-       fi
-       CFLAGS="$pam_save_CFLAGS"
-       CPPFLAGS="$pam_save_CPPFLAGS"
-
-
+ERLANG_LIB_VER_mnesia=$ac_cv_erlang_lib_ver_mnesia
 
+if test "$ac_cv_erlang_lib_dir_mnesia" = "not found"; then :
+  as_fn_error $? "Erlang application 'mnesia' was not found" "$LINENO" 5
 fi
 
-
-# Check whether --enable-hipe was given.
-if test "${enable_hipe+set}" = set; then :
-  enableval=$enable_hipe; case "${enableval}" in
-  yes) hipe=true ;;
-  no)  hipe=false ;;
-  *) as_fn_error $? "bad value ${enableval} for --enable-hipe" "$LINENO" 5 ;;
-esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'inets' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'inets' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_inets+set}" = set; then :
+  $as_echo_n "(cached) " >&6
 else
-  hipe=false
-fi
-
-
-
-# Check whether --enable-roster_gateway_workaround was given.
-if test "${enable_roster_gateway_workaround+set}" = set; then :
-  enableval=$enable_roster_gateway_workaround; case "${enableval}" in
-  yes) roster_gateway_workaround=true ;;
-  no)  roster_gateway_workaround=false ;;
-  *) as_fn_error $? "bad value ${enableval} for --enable-roster-gateway-workaround" "$LINENO" 5 ;;
-esac
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-  roster_gateway_workaround=false
-fi
-
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
+start() ->
+           ReturnValue = case code:lib_dir("inets") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
-# Check whether --enable-mssql was given.
-if test "${enable_mssql+set}" = set; then :
-  enableval=$enable_mssql; case "${enableval}" in
-  yes) db_type=mssql ;;
-  no)  db_type=generic ;;
-  *) as_fn_error $? "bad value ${enableval} for --enable-mssql" "$LINENO" 5 ;;
-esac
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_inets=`cat conftest.out`
+        rm -f conftest.out
 else
-  db_type=generic
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_inets="not found"
+            rm -f conftest.out
+        fi
 fi
-
-
-
-# Check whether --enable-transient_supervisors was given.
-if test "${enable_transient_supervisors+set}" = set; then :
-  enableval=$enable_transient_supervisors; case "${enableval}" in
-  yes) transient_supervisors=true ;;
-  no)  transient_supervisors=false ;;
-  *) as_fn_error $? "bad value ${enableval} for --enable-transient_supervisors" "$LINENO" 5 ;;
-esac
-else
-  transient_supervisors=true
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-
-# Check whether --enable-full_xml was given.
-if test "${enable_full_xml+set}" = set; then :
-  enableval=$enable_full_xml; case "${enableval}" in
-  yes) full_xml=true ;;
-  no)  full_xml=false ;;
-  *) as_fn_error $? "bad value ${enableval} for --enable-full-xml" "$LINENO" 5 ;;
-esac
-else
-  full_xml=false
 fi
-
-
-
-# Check whether --enable-nif was given.
-if test "${enable_nif+set}" = set; then :
-  enableval=$enable_nif; case "${enableval}" in
-  yes) nif=true ;;
-  no)  nif=false ;;
-  *) as_fn_error $? "bad value ${enableval} for --enable-nif" "$LINENO" 5 ;;
-esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_inets" >&5
+$as_echo "$ac_cv_erlang_lib_dir_inets" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'inets' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'inets' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_inets+set}" = set; then :
+  $as_echo_n "(cached) " >&6
 else
-  nif=false
+  if test "$ac_cv_erlang_lib_dir_inets" = "not found"; then :
+  ac_cv_erlang_lib_ver_inets="not found"
+else
+  ac_cv_erlang_lib_ver_inets=`$as_echo "$ac_cv_erlang_lib_dir_inets" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_inets" >&5
+$as_echo "$ac_cv_erlang_lib_ver_inets" >&6; }
+ERLANG_LIB_DIR_inets=$ac_cv_erlang_lib_dir_inets
 
+ERLANG_LIB_VER_inets=$ac_cv_erlang_lib_ver_inets
 
-
-ac_config_files="$ac_config_files Makefile $make_mod_irc $make_mod_muc $make_mod_pubsub $make_mod_proxy65 $make_eldap $make_pam $make_web mysql/Makefile pgsql/Makefile stringprep/Makefile stun/Makefile $make_tls $make_odbc $make_ejabberd_zlib"
-
-#openssl
-
-# Check whether --with-openssl was given.
-if test "${with_openssl+set}" = set; then :
-  withval=$with_openssl;
+if test "$ac_cv_erlang_lib_dir_inets" = "not found"; then :
+  as_fn_error $? "Erlang application 'inets' was not found" "$LINENO" 5
 fi
 
-unset SSL_LIBS;
-unset SSL_CFLAGS;
-have_openssl=no
-if test x"$tls" != x; then
-    for ssl_prefix in $withval /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do
-        printf "looking for openssl in $ssl_prefix...\n"
-        SSL_CFLAGS="-I$ssl_prefix/include"
-        SSL_LIBS="-L$ssl_prefix/lib -lcrypto"
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5
-$as_echo_n "checking for SSL_new in -lssl... " >&6; }
-if ${ac_cv_lib_ssl_SSL_new+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'compiler' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'compiler' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_compiler+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lssl  $SSL_LIBS $SSL_CFLAGS  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char SSL_new ();
-int
-main ()
-{
-return SSL_new ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_ssl_SSL_new=yes
-else
-  ac_cv_lib_ssl_SSL_new=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5
-$as_echo "$ac_cv_lib_ssl_SSL_new" >&6; }
-if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then :
-   have_openssl=yes
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-   have_openssl=no
-fi
-
-        if test x"$have_openssl" = xyes; then
-            save_CPPFLAGS=$CPPFLAGS
-            CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS"
-            for ac_header in openssl/ssl.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default"
-if test "x$ac_cv_header_openssl_ssl_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_OPENSSL_SSL_H 1
-_ACEOF
- have_openssl_h=yes
-fi
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
-done
+start() ->
+           ReturnValue = case code:lib_dir("compiler") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
-            CPPFLAGS=$save_CPPFLAGS
-            if test x"$have_openssl_h" = xyes; then
-                have_openssl=yes
-                printf "openssl found in $ssl_prefix\n";
-                SSL_LIBS="-L$ssl_prefix/lib -lssl -lcrypto"
-                CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS"
-                SSL_CFLAGS="-DHAVE_SSL"
-                break
-            fi
-       else
-           # Clear this from the autoconf cache, so in the next pass of
-           # this loop with different -L arguments, it will test again.
-           unset ac_cv_lib_ssl_SSL_new
-        fi
-    done
-if test x${have_openssl} != xyes; then
-    as_fn_error $? "Could not find development files of OpenSSL library. Install them or disable \`tls' with: --disable-tls" "$LINENO" 5
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_compiler=`cat conftest.out`
+        rm -f conftest.out
+else
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_compiler="not found"
+            rm -f conftest.out
+        fi
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-
-# If ssl is kerberized it need krb5.h
-# On RedHat and OpenBSD, krb5.h is in an unsual place:
-KRB5_INCLUDE="`krb5-config --cflags 2>/dev/null`"
-if test -n "$KRB5_INCLUDE" ; then
-        CPPFLAGS="$CPPFLAGS $KRB5_INCLUDE"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_compiler" >&5
+$as_echo "$ac_cv_erlang_lib_dir_compiler" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'compiler' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'compiler' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_compiler+set}" = set; then :
+  $as_echo_n "(cached) " >&6
 else
-        #         For RedHat                                  For BSD
-        for D in /usr/kerberos/include /usr/include/kerberos /usr/include/kerberosV
-        do
-                if test -d $D ; then
-                        CPPFLAGS="$CPPFLAGS -I$D"
-                fi
-        done
+  if test "$ac_cv_erlang_lib_dir_compiler" = "not found"; then :
+  ac_cv_erlang_lib_ver_compiler="not found"
+else
+  ac_cv_erlang_lib_ver_compiler=`$as_echo "$ac_cv_erlang_lib_dir_compiler" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-ac_fn_c_check_header_mongrel "$LINENO" "krb5.h" "ac_cv_header_krb5_h" "$ac_includes_default"
-if test "x$ac_cv_header_krb5_h" = xyes; then :
-
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_compiler" >&5
+$as_echo "$ac_cv_erlang_lib_ver_compiler" >&6; }
+ERLANG_LIB_DIR_compiler=$ac_cv_erlang_lib_dir_compiler
 
+ERLANG_LIB_VER_compiler=$ac_cv_erlang_lib_ver_compiler
 
-
-ENABLEUSER=""
-# Check whether --enable-user was given.
-if test "${enable_user+set}" = set; then :
-  enableval=$enable_user; case "${enableval}" in
-     yes) ENABLEUSER=`whoami` ;;
-     no) ENABLEUSER="" ;;
-     *) ENABLEUSER=$enableval
-   esac
+if test "$ac_cv_erlang_lib_dir_compiler" = "not found"; then :
+  as_fn_error $? "Erlang application 'compiler' was not found" "$LINENO" 5
 fi
 
-if test "$ENABLEUSER" != ""; then
-  echo "allow this system user to start ejabberd: $ENABLEUSER"
-  INSTALLUSER=$ENABLEUSER
+if test "x$odbc" = "xtrue"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'odbc' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'odbc' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_odbc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
+else
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
-fi
+start() ->
+           ReturnValue = case code:lib_dir("odbc") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
 
-ac_fn_c_check_header_mongrel "$LINENO" "openssl/md2.h" "ac_cv_header_openssl_md2_h" "$ac_includes_default"
-if test "x$ac_cv_header_openssl_md2_h" = xyes; then :
-  md2=true
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_odbc=`cat conftest.out`
+        rm -f conftest.out
 else
-  md2=false
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_odbc="not found"
+            rm -f conftest.out
+        fi
 fi
-
-
-
-
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
-
-
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_build_alias=$build_alias
-test "x$ac_build_alias" = x &&
-  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
-test "x$ac_build_alias" = x &&
-  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
-case $ac_cv_build in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
-esac
-build=$ac_cv_build
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_build
-shift
-build_cpu=$1
-build_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-build_os=$*
-IFS=$ac_save_IFS
-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_odbc" >&5
+$as_echo "$ac_cv_erlang_lib_dir_odbc" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'odbc' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'odbc' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_odbc+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  if test "x$host_alias" = x; then
-  ac_cv_host=$ac_cv_build
+  if test "$ac_cv_erlang_lib_dir_odbc" = "not found"; then :
+  ac_cv_erlang_lib_ver_odbc="not found"
 else
-  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+  ac_cv_erlang_lib_ver_odbc=`$as_echo "$ac_cv_erlang_lib_dir_odbc" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
-case $ac_cv_host in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
-esac
-host=$ac_cv_host
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_host
-shift
-host_cpu=$1
-host_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-host_os=$*
-IFS=$ac_save_IFS
-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
-$as_echo_n "checking target system type... " >&6; }
-if ${ac_cv_target+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test "x$target_alias" = x; then
-  ac_cv_target=$ac_cv_host
-else
-  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_odbc" >&5
+$as_echo "$ac_cv_erlang_lib_ver_odbc" >&6; }
+ERLANG_LIB_DIR_odbc=$ac_cv_erlang_lib_dir_odbc
+
+ERLANG_LIB_VER_odbc=$ac_cv_erlang_lib_ver_odbc
+
+if test "$ac_cv_erlang_lib_dir_odbc" = "not found"; then :
+  as_fn_error $? "Erlang application 'odbc' was not found" "$LINENO" 5
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
-$as_echo "$ac_cv_target" >&6; }
-case $ac_cv_target in
-*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
-esac
-target=$ac_cv_target
-ac_save_IFS=$IFS; IFS='-'
-set x $ac_cv_target
-shift
-target_cpu=$1
-target_vendor=$2
-shift; shift
-# Remember, the first character of IFS is used to create $*,
-# except with old shells:
-target_os=$*
-IFS=$ac_save_IFS
-case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
-
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-test -n "$target_alias" &&
-  test "$program_prefix$program_suffix$program_transform_name" = \
-    NONENONEs,x,x, &&
-  program_prefix=${target_alias}-
-
-#AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$target")
-#AC_SUBST(target_os)
-
-
-case "$target_os" in
-    *darwin*)
-       echo "Target OS is 'Darwin'"
-       ac_ext=erl
+if test "x$tools" = "xtrue"; then
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'tools' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'tools' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_tools+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=erl
 ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
 ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
-
-       if test -n "$ERLC"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erlc" >&5
-$as_echo_n "checking for erlc... " >&6; }
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5
-$as_echo "$ERLC" >&6; }
-else
-    if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}erlc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ERLC+:} false; then :
-  $as_echo_n "(cached) " >&6
+     if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
-  case $ERLC in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
+  cat > conftest.$ac_ext <<_ACEOF
+-module(conftest).
+-export([start/0]).
 
-  ;;
-esac
-fi
-ERLC=$ac_cv_path_ERLC
-if test -n "$ERLC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5
-$as_echo "$ERLC" >&6; }
+start() ->
+           ReturnValue = case code:lib_dir("tools") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
+.
+
+_ACEOF
+if ac_fn_erl_try_run "$LINENO"; then :
+  ac_cv_erlang_lib_dir_tools=`cat conftest.out`
+        rm -f conftest.out
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_tools="not found"
+            rm -f conftest.out
+        fi
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 fi
-if test -z "$ac_cv_path_ERLC"; then
-  ac_pt_ERLC=$ERLC
-  # Extract the first word of "erlc", so it can be a program name with args.
-set dummy erlc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_ERLC+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_tools" >&5
+$as_echo "$ac_cv_erlang_lib_dir_tools" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'tools' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'tools' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_tools+set}" = set; then :
   $as_echo_n "(cached) " >&6
 else
-  case $ac_pt_ERLC in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
-fi
-ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC
-if test -n "$ac_pt_ERLC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERLC" >&5
-$as_echo "$ac_pt_ERLC" >&6; }
+  if test "$ac_cv_erlang_lib_dir_tools" = "not found"; then :
+  ac_cv_erlang_lib_ver_tools="not found"
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  ac_cv_erlang_lib_ver_tools=`$as_echo "$ac_cv_erlang_lib_dir_tools" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
 fi
-
-  if test "x$ac_pt_ERLC" = x; then
-    ERLC=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    ERLC=$ac_pt_ERLC
-  fi
-else
-  ERLC="$ac_cv_path_ERLC"
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_tools" >&5
+$as_echo "$ac_cv_erlang_lib_ver_tools" >&6; }
+ERLANG_LIB_DIR_tools=$ac_cv_erlang_lib_dir_tools
 
-fi
+ERLANG_LIB_VER_tools=$ac_cv_erlang_lib_ver_tools
 
+if test "$ac_cv_erlang_lib_dir_tools" = "not found"; then :
+  as_fn_error $? "Erlang application 'tools' was not found" "$LINENO" 5
+fi
 
-if test "$cross_compiling" = yes; then :
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'runtime_tools' library subdirectory" >&5
+$as_echo_n "checking for Erlang/OTP 'runtime_tools' library subdirectory... " >&6; }
+if test "${ac_cv_erlang_lib_dir_runtime_tools+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=erl
+ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5'
+ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext'
+     if test "$cross_compiling" = yes; then :
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot run test program while cross compiling
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
 else
   cat > conftest.$ac_ext <<_ACEOF
 -module(conftest).
 -export([start/0]).
 
 start() ->
-            halt(case erlang:system_info(wordsize) of
-            8 -> 0; 4 -> 1 end)
+           ReturnValue = case code:lib_dir("runtime_tools") of
+           {error, bad_name} ->
+               file:write_file("conftest.out", "not found\n"),
+               1;
+           LibDir ->
+               file:write_file("conftest.out", LibDir),
+               0
+           end,
+           halt(ReturnValue)
 .
 
 _ACEOF
 if ac_fn_erl_try_run "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: found 64-bit Erlang" >&5
-$as_echo "$as_me: found 64-bit Erlang" >&6;}
-            CBIT=-m64
+  ac_cv_erlang_lib_dir_runtime_tools=`cat conftest.out`
+        rm -f conftest.out
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: found 32-bit Erlang" >&5
-$as_echo "$as_me: found 32-bit Erlang" >&6;}
-            CBIT=-m32
+  if test ! -f conftest.out; then
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "test Erlang program execution failed
+See \`config.log' for more details" "$LINENO" 5 ; }
+        else
+            ac_cv_erlang_lib_dir_runtime_tools="not found"
+            rm -f conftest.out
+        fi
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-       ;;
-    *)
-       echo "Target OS is '$target_os'"
-       CBIT=""
-       ;;
-esac
-CFLAGS="$CFLAGS $CBIT"
-LD_SHARED="$LD_SHARED $CBIT"
-echo "CBIT is set to '$CBIT'"
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_dir_runtime_tools" >&5
+$as_echo "$ac_cv_erlang_lib_dir_runtime_tools" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Erlang/OTP 'runtime_tools' library version" >&5
+$as_echo_n "checking for Erlang/OTP 'runtime_tools' library version... " >&6; }
+if test "${ac_cv_erlang_lib_ver_runtime_tools+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$ac_cv_erlang_lib_dir_runtime_tools" = "not found"; then :
+  ac_cv_erlang_lib_ver_runtime_tools="not found"
+else
+  ac_cv_erlang_lib_ver_runtime_tools=`$as_echo "$ac_cv_erlang_lib_dir_runtime_tools" | sed -n -e 's,^.*-\([^/-]*\)$,\1,p'`
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_erlang_lib_ver_runtime_tools" >&5
+$as_echo "$ac_cv_erlang_lib_ver_runtime_tools" >&6; }
+ERLANG_LIB_DIR_runtime_tools=$ac_cv_erlang_lib_dir_runtime_tools
+
+ERLANG_LIB_VER_runtime_tools=$ac_cv_erlang_lib_ver_runtime_tools
+
+if test "$ac_cv_erlang_lib_dir_runtime_tools" = "not found"; then :
+  as_fn_error $? "Erlang application 'runtime_tools' was not found" "$LINENO" 5
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -5188,21 +3918,10 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    if test "x$cache_file" != "x/dev/null"; then
+    test "x$cache_file" != "x/dev/null" &&
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-      if test ! -f "$cache_file" || test -h "$cache_file"; then
-       cat confcache >"$cache_file"
-      else
-        case $cache_file in #(
-        */* | ?:*)
-         mv -f confcache "$cache_file"$$ &&
-         mv -f "$cache_file"$$ "$cache_file" ;; #(
-        *)
-         mv -f confcache "$cache_file" ;;
-       esac
-      fi
-    fi
+    cat confcache >$cache_file
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -5270,7 +3989,7 @@ LTLIBOBJS=$ac_ltlibobjs
 
 
 
-: "${CONFIG_STATUS=./config.status}"
+: ${CONFIG_STATUS=./config.status}
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -5371,7 +4090,6 @@ fi
 IFS=" ""       $as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -5678,8 +4396,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by ejabberd $as_me 13.03-beta2, which was
-generated by GNU Autoconf 2.68.  Invocation command line was
+This file was extended by ejabberd $as_me 3.0.0, which was
+generated by GNU Autoconf 2.67.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -5731,8 +4449,8 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-ejabberd config.status 13.03-beta2
-configured by $0, generated by GNU Autoconf 2.68,
+ejabberd config.status 3.0.0
+configured by $0, generated by GNU Autoconf 2.67,
   with options \\"\$ac_cs_config\\"
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -5741,6 +4459,7 @@ gives unlimited permission to copy, distribute and modify it."
 
 ac_pwd='$ac_pwd'
 srcdir='$srcdir'
+INSTALL='$INSTALL'
 test -n "\$AWK" || AWK=awk
 _ACEOF
 
@@ -5842,22 +4561,10 @@ for ac_config_target in $ac_config_targets
 do
   case $ac_config_target in
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-    "$make_mod_irc") CONFIG_FILES="$CONFIG_FILES $make_mod_irc" ;;
-    "$make_mod_muc") CONFIG_FILES="$CONFIG_FILES $make_mod_muc" ;;
-    "$make_mod_pubsub") CONFIG_FILES="$CONFIG_FILES $make_mod_pubsub" ;;
-    "$make_mod_proxy65") CONFIG_FILES="$CONFIG_FILES $make_mod_proxy65" ;;
-    "$make_eldap") CONFIG_FILES="$CONFIG_FILES $make_eldap" ;;
-    "$make_pam") CONFIG_FILES="$CONFIG_FILES $make_pam" ;;
-    "$make_web") CONFIG_FILES="$CONFIG_FILES $make_web" ;;
-    "mysql/Makefile") CONFIG_FILES="$CONFIG_FILES mysql/Makefile" ;;
-    "pgsql/Makefile") CONFIG_FILES="$CONFIG_FILES pgsql/Makefile" ;;
-    "stringprep/Makefile") CONFIG_FILES="$CONFIG_FILES stringprep/Makefile" ;;
-    "stun/Makefile") CONFIG_FILES="$CONFIG_FILES stun/Makefile" ;;
-    "$make_tls") CONFIG_FILES="$CONFIG_FILES $make_tls" ;;
-    "$make_odbc") CONFIG_FILES="$CONFIG_FILES $make_odbc" ;;
-    "$make_ejabberd_zlib") CONFIG_FILES="$CONFIG_FILES $make_ejabberd_zlib" ;;
-
-  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+    "vars.config") CONFIG_FILES="$CONFIG_FILES vars.config" ;;
+    "src/ejabberd.app.src") CONFIG_FILES="$CONFIG_FILES src/ejabberd.app.src" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
   esac
 done
 
@@ -5878,10 +4585,9 @@ fi
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp= ac_tmp=
+  tmp=
   trap 'exit_status=$?
-  : "${ac_tmp:=$tmp}"
-  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
 ' 0
   trap 'as_fn_exit 1' 1 2 13 15
 }
@@ -5889,13 +4595,12 @@ $debug ||
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -d "$tmp"
+  test -n "$tmp" && test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
 } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-ac_tmp=$tmp
 
 # Set up the scripts for CONFIG_FILES section.
 # No need to generate them if there are no CONFIG_FILES.
@@ -5917,7 +4622,7 @@ else
   ac_cs_awk_cr=$ac_cr
 fi
 
-echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
 _ACEOF
 
 
@@ -5945,7 +4650,7 @@ done
 rm -f conf$$subs.sh
 
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
 sed -n '
 h
@@ -5993,7 +4698,7 @@ t delim
 rm -f conf$$subs.awk
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
   FS = "\a"
 
@@ -6025,7 +4730,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
   sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
 else
   cat
-fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
   || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
@@ -6065,7 +4770,7 @@ do
   esac
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
   esac
@@ -6084,7 +4789,7 @@ do
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$ac_tmp/stdin";;
+      -) ac_f="$tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
         # (if the path is not absolute).  The absolute path cannot be DOS-style,
         # because $ac_f cannot contain `:'.
@@ -6093,7 +4798,7 @@ do
           [\\/$]*) false;;
           *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
           esac ||
-          as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+          as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
       esac
       case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
@@ -6119,8 +4824,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
     esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$ac_tmp/stdin" \
-      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5  ;;
     esac
     ;;
   esac
@@ -6190,6 +4895,10 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
   # CONFIG_FILE
   #
 
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
 _ACEOF
 
 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
@@ -6243,24 +4952,24 @@ s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
 s&@builddir@&$ac_builddir&;t t
 s&@abs_builddir@&$ac_abs_builddir&;t t
 s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
 $ac_datarootdir_hack
 "
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
-  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' \
-      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&5
 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&2;}
 
-  rm -f "$ac_tmp/stdin"
+  rm -f "$tmp/stdin"
   case $ac_file in
-  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
-  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
   esac \
   || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..d3efb80
--- /dev/null
@@ -0,0 +1,283 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.53)
+AC_PACKAGE_VERSION(3.0.0)
+AC_INIT(ejabberd, 3.0.0, [ejabberd@process-one.net], [ejabberd])
+REQUIRE_ERLANG_MIN="5.9.1 (Erlang/OTP R15B01)"
+REQUIRE_ERLANG_MAX="9.0.0 (No Max)"
+
+# Checks for programs.
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+AC_PROG_SED
+
+if test "x$GCC" = "xyes"; then
+    CFLAGS="$CFLAGS -Wall"
+fi
+
+# Checks Erlang runtime and compiler
+AC_ARG_WITH(erlang,
+       AC_HELP_STRING([--with-erlang=dir],
+               [search for erlang in dir]),
+[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_erlang" = "X"; then
+    extra_erl_path=""
+else
+    extra_erl_path="$with_erlang:$with_erlang/bin:"
+fi
+])
+
+AC_PATH_TOOL(ERL, erl, , [${extra_erl_path}$PATH])
+AC_PATH_TOOL(ERLC, erlc, , [${extra_erl_path}$PATH])
+
+AC_ERLANG_NEED_ERL
+AC_ERLANG_NEED_ERLC
+
+AC_ARG_ENABLE(erlang-version-check,
+[AC_HELP_STRING([--enable-erlang-version-check],
+       [Check Erlang/OTP version @<:@default=yes@:>@])])
+       case "$enable_erlang_version_check" in
+       yes|'')
+               ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX])
+               ;;
+       no)
+               ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX],[warn])
+               ;;
+esac
+
+# Checks and sets ERLANG_ROOT_DIR and ERLANG_LIB_DIR variable
+AC_ERLANG_SUBST_ROOT_DIR
+# AC_ERLANG_SUBST_LIB_DIR
+
+#locating escript
+AC_PATH_PROG([ESCRIPT], [escript], [], [$ERLANG_ROOT_DIR/bin])
+
+#locating make
+AC_CHECK_PROG([MAKE], [make], [make], [])
+
+if test "x$ESCRIPT" = "x"; then
+   AC_MSG_ERROR(['escript' was not found])
+fi
+
+if test "x$MAKE" = "x"; then
+   AC_MSG_ERROR(['make' was not found])
+fi
+
+# Change default prefix
+AC_PREFIX_DEFAULT(/)
+
+AC_ARG_ENABLE(hipe,
+[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
+[case "${enableval}" in
+  yes) hipe=true ;;
+  no)  hipe=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-hipe) ;;
+esac],[hipe=false])
+
+AC_ARG_ENABLE(roster_gateway_workaround,
+[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
+[case "${enableval}" in
+  yes) roster_gateway_workaround=true ;;
+  no)  roster_gateway_workaround=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
+esac],[roster_gateway_workaround=false])
+
+AC_ARG_ENABLE(transient_supervisors,
+[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: no)])],
+[case "${enableval}" in
+  yes) transient_supervisors=true ;;
+  no)  transient_supervisors=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-transient_supervisors) ;;
+esac],[transient_supervisors=false])
+
+AC_ARG_ENABLE(full_xml,
+[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
+[case "${enableval}" in
+  yes) full_xml=true ;;
+  no)  full_xml=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;;
+esac],[full_xml=false])
+
+AC_ARG_ENABLE(mssql,
+[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
+[case "${enableval}" in
+  yes) db_type=mssql ;;
+  no)  db_type=generic ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
+esac],[db_type=generic])
+
+AC_ARG_ENABLE(tools,
+[AC_HELP_STRING([--enable-tools], [build development tools (currently the ejabberd profiler only, default: no)])],
+[case "${enableval}" in
+  yes) tools=true ;;
+  no)  tools=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
+esac],[tools=false])
+
+AC_ARG_ENABLE(all,
+[AC_HELP_STRING([--enable-all], [same as --enable-nif --enable-odbc --enable-mysql --enable-pgsql --enable-pam --enable-zlib --enable-stun --enable-json --enable-iconv --enable-debug --enable-http (useful for Dialyzer checks, default: no)])],
+[case "${enableval}" in
+  yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true stun=true json=true iconv=true debug=true http=true ;;
+  no) nif=false odbc=false mysql=false pgsql=false pam=false zlib=false stun=false json=false iconv=false debug=false http=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
+esac],[])
+
+AC_ARG_ENABLE(nif,
+[AC_HELP_STRING([--enable-nif], [replace some functions with C equivalents. Requires Erlang R13B04 or higher (default: no)])],
+[case "${enableval}" in
+  yes) nif=true ;;
+  no)  nif=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-nif) ;;
+esac],[if test "x$nif" = "x"; then nif=false; fi])
+
+AC_ARG_ENABLE(odbc,
+[AC_HELP_STRING([--enable-odbc], [enable pure ODBC support (default: no)])],
+[case "${enableval}" in
+  yes) odbc=true ;;
+  no)  odbc=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-odbc) ;;
+esac],[if test "x$odbc" = "x"; then odbc=false; fi])
+
+AC_ARG_ENABLE(mysql,
+[AC_HELP_STRING([--enable-mysql], [enable MySQL support (default: no)])],
+[case "${enableval}" in
+  yes) mysql=true ;;
+  no)  mysql=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-mysql) ;;
+esac],[if test "x$mysql" = "x"; then mysql=false; fi])
+
+AC_ARG_ENABLE(pgsql,
+[AC_HELP_STRING([--enable-pgsql], [enable PostgreSQL support (default: no)])],
+[case "${enableval}" in
+  yes) pgsql=true ;;
+  no)  pgsql=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-pgsql) ;;
+esac],[if test "x$pgsql" = "x"; then pgsql=false; fi])
+
+AC_ARG_ENABLE(pam,
+[AC_HELP_STRING([--enable-pam], [enable PAM support (default: no)])],
+[case "${enableval}" in
+  yes) pam=true ;;
+  no)  pam=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-pam) ;;
+esac],[if test "x$pam" = "x"; then pam=false; fi])
+
+AC_ARG_ENABLE(zlib,
+[AC_HELP_STRING([--enable-zlib], [enable Stream Compression (XEP-0138) using zlib (default: yes)])],
+[case "${enableval}" in
+  yes) zlib=true ;;
+  no)  zlib=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
+esac],[if test "x$zlib" = "x"; then zlib=true; fi])
+
+AC_ARG_ENABLE(stun,
+[AC_HELP_STRING([--enable-stun], [enable STUN support (default: no)])],
+[case "${enableval}" in
+  yes) stun=true ;;
+  no)  stun=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-stun) ;;
+esac],[if test "x$stun" = "x"; then stun=false; fi])
+
+AC_ARG_ENABLE(json,
+[AC_HELP_STRING([--enable-json], [enable JSON support for mod_bosh (default: no)])],
+[case "${enableval}" in
+  yes) json=true ;;
+  no)  json=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-json) ;;
+esac],[if test "x$json" = "x"; then json=false; fi])
+
+AC_ARG_ENABLE(iconv,
+[AC_HELP_STRING([--enable-iconv], [enable iconv support (default: yes)])],
+[case "${enableval}" in
+  yes) iconv=true ;;
+  no)  iconv=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-iconv) ;;
+esac],[if test "x$iconv" = "x"; then iconv=true; fi])
+
+AC_ARG_ENABLE(debug,
+[AC_HELP_STRING([--enable-debug], [enable debug information (default: yes)])],
+[case "${enableval}" in
+  yes) debug=true ;;
+  no)  debug=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
+esac],[if test "x$debug" = "x"; then debug=true; fi])
+
+AC_ARG_ENABLE(http,
+[AC_HELP_STRING([--enable-http], [build external HTTP libraries ('ibrowse' and 'lhttpc', default: no)])],
+[case "${enableval}" in
+  yes) http=true ;;
+  no)  http=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-http) ;;
+esac],[if test "x$http" = "x"; then http=false; fi])
+
+AC_ARG_ENABLE(lager,
+[AC_HELP_STRING([--enable-lager], [enable lager support (default: yes)])],
+[case "${enableval}" in
+  yes) lager=true ;;
+  no)  lager=false ;;
+  *) AC_MSG_ERROR(bad value ${enableval} for --enable-lager) ;;
+esac],[if test "x$lager" = "x"; then lager=true; fi])
+
+AC_CONFIG_FILES([Makefile
+                vars.config
+                src/ejabberd.app.src])
+
+ENABLEUSER=""
+AC_ARG_ENABLE(user,
+  [AS_HELP_STRING([--enable-user[[[[=USER]]]]], [allow this system user to start ejabberd (default: no)])],
+  [case "${enableval}" in
+     yes) ENABLEUSER=`whoami` ;;
+     no) ENABLEUSER="" ;;
+     *) ENABLEUSER=$enableval
+   esac],
+  [])
+if test "$ENABLEUSER" != ""; then
+  echo "allow this system user to start ejabberd: $ENABLEUSER"
+  AC_SUBST([INSTALLUSER], [$ENABLEUSER])
+fi
+
+AC_ERLANG_CHECK_LIB([sasl], [],
+    [AC_MSG_ERROR([Erlang application 'sasl' was not found])])
+AC_ERLANG_CHECK_LIB([crypto], [],
+    [AC_MSG_ERROR([Erlang application 'crypto' was not found])])
+AC_ERLANG_CHECK_LIB([public_key], [],
+    [AC_MSG_ERROR([Erlang application 'public_key' was not found])])
+AC_ERLANG_CHECK_LIB([ssl], [],
+    [AC_MSG_ERROR([Erlang application 'ssl' was not found])])
+AC_ERLANG_CHECK_LIB([mnesia], [],
+    [AC_MSG_ERROR([Erlang application 'mnesia' was not found])])
+AC_ERLANG_CHECK_LIB([inets], [],
+    [AC_MSG_ERROR([Erlang application 'inets' was not found])])
+AC_ERLANG_CHECK_LIB([compiler], [],
+    [AC_MSG_ERROR([Erlang application 'compiler' was not found])])
+if test "x$odbc" = "xtrue"; then
+   AC_ERLANG_CHECK_LIB([odbc], [],
+      [AC_MSG_ERROR([Erlang application 'odbc' was not found])])
+fi
+if test "x$tools" = "xtrue"; then
+   AC_ERLANG_CHECK_LIB([tools], [],
+      [AC_MSG_ERROR([Erlang application 'tools' was not found])])
+   AC_ERLANG_CHECK_LIB([runtime_tools], [],
+      [AC_MSG_ERROR([Erlang application 'runtime_tools' was not found])])
+fi
+
+AC_SUBST(hipe)
+AC_SUBST(roster_gateway_workaround)
+AC_SUBST(transient_supervisors)
+AC_SUBST(full_xml)
+AC_SUBST(nif)
+AC_SUBST(db_type)
+AC_SUBST(odbc)
+AC_SUBST(mysql)
+AC_SUBST(pgsql)
+AC_SUBST(pam)
+AC_SUBST(zlib)
+AC_SUBST(stun)
+AC_SUBST(json)
+AC_SUBST(iconv)
+AC_SUBST(debug)
+AC_SUBST(http)
+AC_SUBST(lager)
+AC_SUBST(tools)
+
+AC_OUTPUT
similarity index 100%
rename from src/configure.bat
rename to configure.bat
index 90f4ac51957563a2a666440384119092b808c737..97bef684c88e05e58334cc59cd750ca0ee4b837e 100644 (file)
@@ -88,6 +88,16 @@ parse_form(Dir, File, Form, Used) ->
         [_, {string, Line, Str}]
        } ->
            process_string(Dir, File, Line, Str, Used);
+       {call,
+        _,
+        {remote, _, {atom, _, translate}, {atom, _, translate}},
+        [_,
+         {bin,_,
+          [{bin_element,_,
+            {string,Line,Str},
+            default,default}]}]
+       } ->
+           process_string(Dir, File, Line, Str, Used);
        {call,
         _,
         {remote, _, {atom, _, translate}, {atom, _, translate}},
@@ -281,8 +291,8 @@ build_additional_translators(List) ->
       List).
 
 print_translation(File, Line, Str, StrT) ->
-    StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""),
-    StrTQ = ejabberd_regexp:greplace(StrT, "\\\"", "\\\\\""),
+    StrQ = ejabberd_regexp:greplace(list_to_binary(Str), <<"\\\"">>, <<"\\\\\"">>),
+    StrTQ = ejabberd_regexp:greplace(list_to_binary(StrT), <<"\\\"">>, <<"\\\\\"">>),
     io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
 
 print_translation_obsolete(Str, StrT) ->
index 9f2d54ad69f67686d4e07c293dfc70ace250f4ad..fcc58cb27c0f6c7843a57e6e4441f82ca1cc7714 100755 (executable)
@@ -15,13 +15,14 @@ prepare_dirs ()
        ERL=`which erl`
 
        EJA_SRC_DIR=$EJA_DIR/src/
-       EJA_MSGS_DIR=$EJA_SRC_DIR/msgs/
+       EJA_MSGS_DIR=$EJA_DIR/priv/msgs/
        EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
        EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl
        EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam
 
        SRC_DIR=$RUN_DIR/src
-       MSGS_DIR=$SRC_DIR/msgs
+       EBIN_DIR=$RUN_DIR/ebin
+       MSGS_DIR=$EJA_DIR/priv/msgs
 
        if !([[ -n $EJA_DIR ]])
        then 
@@ -155,7 +156,8 @@ extract_lang_srcmsg2po ()
 
        echo $MSGS_PATH
 
-       $ERL -pa $EXTRACT_DIR -pa $SRC_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1
+       cd $SRC_DIR
+       $ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1
        sed -e 's/ \[\]$/ \"\"/g;' $PO_PATH.1 > $PO_PATH.2
        msguniq --sort-by-file $PO_PATH.2 --output-file=$PO_PATH
        
@@ -174,7 +176,7 @@ extract_lang_src2pot ()
        echo "" >>$MSGS_PATH
 
        cd $SRC_DIR
-       $ERL -pa $EXTRACT_DIR -pa $SRC_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1
+       $ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1
        sed -e 's/ \[\]$/ \"\"/g;' $POT_PATH.1 > $POT_PATH.2
 
        #msguniq --sort-by-file $POT_PATH.2 $EJA_MSGS_DIR --output-file=$POT_PATH
@@ -288,8 +290,8 @@ translation_instructions ()
        echo "  $MSGS_PATH"
 }
 
-EJA_DIR=`pwd`/..
-RUN_DIR=`pwd`/..
+EJA_DIR=`pwd`
+RUN_DIR=`pwd`
 PROJECT=ejabberd
 
 while [ $# -ne 0 ] ; do
index 69ddd3697b5287cc1c2facfa6760befcdfc9d7aa..5ec3a2ed45db52841f622975b3cb3ccd970fac1a 100644 (file)
@@ -375,10 +375,31 @@ Some options that you may be interested in modifying:
        \titem{--enable-pam}
        Enable the PAM authentication method (see section \ref{pam}).
 
-       \titem{--enable-odbc or --enable-mssql}
+       \titem{--enable-mssql}
        Required if you want to use an external database.
        See section~\ref{database} for more information.
 
+        \titem{--enable-tools}
+        Enable the use of development tools.
+
+        \titem{--enable-mysql}
+        Enable MySQL support (see section \ref{mysql}).
+
+        \titem{--enable-pgsql}
+        Enable PostgreSQL support (see section \ref{pgsql}).
+
+        \titem{--enable-zlib}
+        Enable Stream Compression (XEP-0138) using zlib.
+
+        \titem{--enable-stun}
+        Enable STUN support (see section \ref{stun}).
+
+        \titem{--enable-iconv}
+        Enable iconv support. This is needed for \term{mod\_irc} (see seciont \ref{modirc}).
+
+        \titem{--enable-debug}
+        Compile with \term{+debug\_info} enabled.
+
        \titem{--enable-full-xml}
        Enable the use of XML based optimisations.
        It will for example use CDATA to escape characters in the XMPP stream.
@@ -1951,28 +1972,22 @@ For example:
 \makesubsection{mysql}{MySQL}
 \ind{MySQL}\ind{MySQL!schema}
 
-This section describes how to create a MySQL database for ejabberd,
-and configure \ejabberd{} to use it to store authentication and user data.
+There is a file \term{mysql.sql} in the directory \term{odbc}.
+This file contains the \ejabberd{} schema for MySQL. At the end of the file
+you can find information to update your database schema.
+
 
 \makesubsubsection{compilemysql}{Driver Compilation}
 \ind{MySQL!Driver Compilation}
 
 You can skip this step if you installed \ejabberd{} using a binary installer or
-if the binary packages of \ejabberd{} you are using include support for MySQL.
+if the binary packages of \ejabberd{} you are using include support for ODBC.
 
-\begin{enumerate}
-\item First, install the Erlang mysql library from
-  \footahref{http://www.ejabberd.im/ejabberd-modules/}{ejabberd-modules SVN repository}.
-  Make sure the compiled
-  files are in your Erlang path; you can put them for example in the same
-  directory as your \ejabberd{} .beam files.
-\item Then, configure and install \ejabberd{} with ODBC support enabled (this is
-  also needed for native MySQL support!). This can be done, by using next
-  commands:
+Use \term{--enable-mysql} configure option in order to build \ejabberd{} with
+MySQL support:
 \begin{verbatim}
-./configure --enable-odbc && make install
+./configure --enable-mysql && make install
 \end{verbatim}
-\end{enumerate}
 
 
 \makesubsubsection{mysqlcreatedb}{Create MySQL database}
@@ -2113,7 +2128,9 @@ module option \term{\{db\_type, odbc\}}.
 \makesubsection{mssql}{Microsoft SQL Server}
 \ind{Microsoft SQL Server}\ind{Microsoft SQL Server!schema}
 
-ejabberd can be configured to use Microsoft SQL Server for storing authentication and other information instead of the internal database. MS SQL Server 2000 is known to be supported. You need an ejabberd with the MSSQL patch.
+There is a file \term{mssql.sql} in the directory \term{odbc}.
+This file contains the \ejabberd{} schema for Microsoft SQL Server. At the end of the file
+you can find information to update your database schema.
 
 
 \makesubsubsection{compilemssql}{Driver Compilation}
@@ -2122,11 +2139,10 @@ ejabberd can be configured to use Microsoft SQL Server for storing authenticatio
 You can skip this step if you installed \ejabberd{} using a binary installer or
 if the binary packages of \ejabberd{} you are using include support for ODBC.
 
-If you want to use Microsoft SQL Server with ODBC, you need to configure,
-compile and install \ejabberd{} with support for ODBC and Microsoft SQL Server
-enabled. This can be done, by using next commands:
+Use \term{--enable-mssql} configure option in order to build \ejabberd{} with
+Microsoft SQL Server support:
 \begin{verbatim}
-./configure --enable-odbc --enable-mssql && make install
+./configure --enable-mssql && make install
 \end{verbatim}
 
 
@@ -2181,8 +2197,10 @@ module option \term{\{db\_type, odbc\}}.
 \makesubsection{pgsql}{PostgreSQL}
 \ind{PostgreSQL}\ind{PostgreSQL!schema}
 
-This section describes how to create a MySQL database for ejabberd,
-and configure \ejabberd{} to use it to store authentication and user data.
+There is a file \term{pg.sql} in the directory \term{odbc}.
+This file contains the \ejabberd{} schema for PostgreSQL. At the end of the file
+you can find information to update your database schema.
+
 
 \makesubsubsection{compilepgsql}{Driver Compilation}
 \ind{PostgreSQL!Driver Compilation}
@@ -2191,19 +2209,11 @@ You can skip this step if you installed \ejabberd{} using a binary installer or
 if the binary packages of \ejabberd{} you are using include support for
 PostgreSQL.
 
-\begin{enumerate}
-\item First, install the Erlang pgsql library from
-  \footahref{http://www.ejabberd.im/ejabberd-modules/}{ejabberd-modules SVN repository}.
-  Make sure the compiled
-  files are in your Erlang path; you can put them for example in the same
-  directory as your \ejabberd{} .beam files.
-\item Then, configure, compile and install \ejabberd{} with ODBC support enabled
-  (this is also needed for native PostgreSQL support!). This can be done, by
-  using next commands:
+Use \term{--enable-pgsql} configure option in order to build \ejabberd{} with
+PostgreSQL support:
 \begin{verbatim}
-./configure --enable-odbc && make install
+./configure --enable-pgsql && make install
 \end{verbatim}
-\end{enumerate}
 
 \makesubsubsection{pgsqlcreatedb}{Create PostgreSQL database}
 \ind{PgSQL!Create database}
@@ -2273,31 +2283,6 @@ module option \term{\{db\_type, odbc\}}.
 \makesubsection{odbc}{ODBC Compatible}
 \ind{databases!ODBC}
 
-Although this section will describe \ejabberd{}'s configuration when you want to
-use the ODBC driver, it does not describe the installation and database creation
-of your database. Check the documentation of your database. The tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} also can help you. Note that the tutorial
-contains information about \ejabberd{}'s configuration which is duplicate to
-this section.
-
-
-\makesubsubsection{compileodbc}{Driver Compilation}
-
-You can skip this step if you installed \ejabberd{} using a binary installer or
-if the binary packages of \ejabberd{} you are using include support for
-ODBC.
-
-\begin{enumerate}
-\item First, install the \footahref{http://support.process-one.net/doc/display/CONTRIBS/Yxa}{Erlang
-  MySQL library}. Make sure the compiled files are in your Erlang path; you can
-  put them for example in the same directory as your \ejabberd{} .beam files.
-\item Then, configure, compile and install \ejabberd{} with ODBC support
-  enabled. This can be done, by using next commands:
-\begin{verbatim}
-./configure --enable-odbc && make install
-\end{verbatim}
-\end{enumerate}
-
-
 \makesubsubsection{configureodbc}{Database Connection}
 \ind{ODBC!Database Connection}
 
old mode 100644 (file)
new mode 100755 (executable)
similarity index 91%
rename from src/ejabberdctl.template
rename to ejabberdctl.template
index b6dfd4f..a98e73e
@@ -7,12 +7,14 @@ ERL_MAX_PORTS=32000
 ERL_PROCESSES=250000
 ERL_MAX_ETS_TABLES=1400
 
+SCRIPT_DIR=$(cd ${0%/*} && pwd)
+
 # define default environment variables
 NODE=ejabberd
 HOST=localhost
 ERLANG_NODE=$NODE@$HOST
-ERL=@erl@
-INSTALLUSER=@installuser@
+ERL={{erl}}
+INSTALLUSER={{installuser}}
 
 # parse command line parameters
 ARGS=
@@ -33,7 +35,7 @@ done
 
 # Define ejabberd variable if they have not been defined from the command line
 if [ "$ETCDIR" = "" ] ; then
-    ETCDIR=@SYSCONFDIR@/ejabberd
+    ETCDIR={{sysconfdir}}/ejabberd
 fi
 if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
     EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg
@@ -43,13 +45,13 @@ if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then
 fi
 [ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
 if [ "$LOGS_DIR" = "" ] ; then
-    LOGS_DIR=@LOCALSTATEDIR@/log/ejabberd
+    LOGS_DIR={{localstatedir}}/log/ejabberd
 fi
 if [ "$SPOOLDIR" = "" ] ; then
-    SPOOLDIR=@LOCALSTATEDIR@/lib/ejabberd
+    SPOOLDIR={{localstatedir}}/lib/ejabberd
 fi
 if [ "$EJABBERD_DOC_PATH" = "" ] ; then
-    EJABBERD_DOC_PATH=@DOCDIR@
+    EJABBERD_DOC_PATH={{docdir}}
 fi
 if [ "$ERLANG_NODE_ARG" != "" ] ; then
     ERLANG_NODE=$ERLANG_NODE_ARG
@@ -88,23 +90,25 @@ fi
 ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
 
 # define additional environment variables
-if [ "$EJABBERDDIR" = "" ]; then
-    EJABBERDDIR=@LIBDIR@/ejabberd
-fi
-if [ "$EJABBERD_EBIN_PATH" = "" ]; then
-    EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin
-fi
-if [ "$EJABBERD_PRIV_PATH" = "" ]; then
-    EJABBERD_PRIV_PATH=$EJABBERDDIR/priv
-fi
-if [ "$EJABBERD_BIN_PATH" = "" ]; then
-    EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin
-fi
-if [ "$EJABBERD_SO_PATH" = "" ]; then
-    EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib
-fi
-if [ "$EJABBERD_MSGS_PATH" = "" ]; then
-    EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs
+if [ "{{release}}" != "true" ] ; then
+    if [ "$EJABBERDDIR" = "" ] ; then
+       EJABBERDDIR={{libdir}}/ejabberd
+    fi
+    if [ "$EJABBERD_EBIN_PATH" = "" ] ; then
+       EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin
+    fi
+    if [ "$EJABBERD_PRIV_PATH" = "" ] ; then
+       EJABBERD_PRIV_PATH=$EJABBERDDIR/priv
+    fi
+    if [ "$EJABBERD_BIN_PATH" = "" ] ; then
+       EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin
+    fi
+    if [ "$EJABBERD_SO_PATH" = "" ] ; then
+       EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib
+    fi
+    if [ "$EJABBERD_MSGS_PATH" = "" ] ; then
+       EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs
+    fi
 fi
 
 EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
@@ -251,7 +255,7 @@ ctl ()
     # using flock if available. Expects a linux-style
     # flock that can lock a file descriptor.
     MAXCONNID=100
-    CONNLOCKDIR=@LOCALSTATEDIR@/lock/ejabberdctl
+    CONNLOCKDIR={{localstatedir}}/lock/ejabberdctl
     FLOCK='/usr/bin/flock'
     if [ ! -x "$FLOCK" ] || [ ! -d "$CONNLOCKDIR" ] ; then
        JOT='/usr/bin/jot'
similarity index 100%
rename from src/adhoc.hrl
rename to include/adhoc.hrl
similarity index 71%
rename from src/ejabberd.hrl
rename to include/ejabberd.hrl
index d2832ee4d1dc8702cf05dd692a36ae648a166e90..736a2aa42db9bef38d70463d412bfc3f2744c29c 100644 (file)
@@ -29,7 +29,7 @@
 
 -define(MYLANG, ejabberd_config:get_mylang()).
 
--define(MSGS_DIR, <<"msgs">>).
+-define(MSGS_DIR, filename:join(["priv", "msgs"])).
 
 -define(CONFIG_PATH, <<"ejabberd.cfg">>).
 
 -type scram() :: #scram{}.
 
 -define(SCRAM_DEFAULT_ITERATION_COUNT, 4096).
-
-%% ---------------------------------
-%% Logging mechanism
-
-%% Print in standard output
--define(PRINT(Format, Args), io:format(Format, Args)).
-
--define(DEBUG(Format, Args),
-       ejabberd_logger:debug_msg(?MODULE, ?LINE, Format,
-                                 Args)).
-
--define(INFO_MSG(Format, Args),
-       ejabberd_logger:info_msg(?MODULE, ?LINE, Format, Args)).
-
--define(WARNING_MSG(Format, Args),
-       ejabberd_logger:warning_msg(?MODULE, ?LINE, Format,
-                                   Args)).
-
--define(ERROR_MSG(Format, Args),
-       ejabberd_logger:error_msg(?MODULE, ?LINE, Format,
-                                 Args)).
-
--define(CRITICAL_MSG(Format, Args),
-       ejabberd_logger:critical_msg(?MODULE, ?LINE, Format,
-                                    Args)).
similarity index 100%
rename from src/eldap/eldap.hrl
rename to include/eldap.hrl
similarity index 100%
rename from src/web/http_bind.hrl
rename to include/http_bind.hrl
similarity index 73%
rename from src/jlib.hrl
rename to include/jlib.hrl
index b0f59e288d278176f082e08eab0c3a780adfe5e4..13fb8fcf4c2044a833c115adca3302f22ffed042 100644 (file)
 %%%
 %%%----------------------------------------------------------------------
 
-
--define(NS_DISCO_ITEMS,
-       <<"http://jabber.org/protocol/disco#items">>).
-
--define(NS_DISCO_INFO,
-       <<"http://jabber.org/protocol/disco#info">>).
-
--define(NS_VCARD, <<"vcard-temp">>).
-
--define(NS_VCARD_UPDATE, <<"vcard-temp:x:update">>).
-
--define(NS_AUTH, <<"jabber:iq:auth">>).
-
--define(NS_AUTH_ERROR, <<"jabber:iq:auth:error">>).
-
--define(NS_REGISTER, <<"jabber:iq:register">>).
-
--define(NS_SEARCH, <<"jabber:iq:search">>).
-
--define(NS_ROSTER, <<"jabber:iq:roster">>).
-
--define(NS_ROSTER_VER,
-       <<"urn:xmpp:features:rosterver">>).
-
--define(NS_PRIVACY, <<"jabber:iq:privacy">>).
-
--define(NS_BLOCKING, <<"urn:xmpp:blocking">>).
-
--define(NS_PRIVATE, <<"jabber:iq:private">>).
-
--define(NS_VERSION, <<"jabber:iq:version">>).
-
--define(NS_TIME90, <<"jabber:iq:time">>).
-
--define(NS_TIME, <<"urn:xmpp:time">>).
-
--define(NS_LAST, <<"jabber:iq:last">>).
-
--define(NS_XDATA, <<"jabber:x:data">>).
-
--define(NS_IQDATA, <<"jabber:iq:data">>).
-
--define(NS_DELAY91, <<"jabber:x:delay">>).
-
--define(NS_DELAY, <<"urn:xmpp:delay">>).
-
--define(NS_EXPIRE, <<"jabber:x:expire">>).
-
--define(NS_EVENT, <<"jabber:x:event">>).
-
--define(NS_CHATSTATES,
-       <<"http://jabber.org/protocol/chatstates">>).
-
--define(NS_XCONFERENCE, <<"jabber:x:conference">>).
-
--define(NS_STATS,
-       <<"http://jabber.org/protocol/stats">>).
-
--define(NS_MUC, <<"http://jabber.org/protocol/muc">>).
-
--define(NS_MUC_USER,
-       <<"http://jabber.org/protocol/muc#user">>).
-
--define(NS_MUC_ADMIN,
-       <<"http://jabber.org/protocol/muc#admin">>).
-
--define(NS_MUC_OWNER,
-       <<"http://jabber.org/protocol/muc#owner">>).
-
--define(NS_MUC_UNIQUE,
-       <<"http://jabber.org/protocol/muc#unique">>).
-
--define(NS_PUBSUB,
-       <<"http://jabber.org/protocol/pubsub">>).
-
--define(NS_PUBSUB_EVENT,
-       <<"http://jabber.org/protocol/pubsub#event">>).
-
--define(NS_PUBSUB_META_DATA,
-       <<"http://jabber.org/protocol/pubsub#meta-data">>).
-
--define(NS_PUBSUB_OWNER,
-       <<"http://jabber.org/protocol/pubsub#owner">>).
-
--define(NS_PUBSUB_NMI,
-       <<"http://jabber.org/protocol/pubsub#node-meta-info">>).
-
--define(NS_PUBSUB_ERRORS,
-       <<"http://jabber.org/protocol/pubsub#errors">>).
-
--define(NS_PUBSUB_NODE_CONFIG,
-       <<"http://jabber.org/protocol/pubsub#node_config">>).
-
--define(NS_PUBSUB_SUB_OPTIONS,
-       <<"http://jabber.org/protocol/pubsub#subscribe_options">>).
-
--define(NS_PUBSUB_SUBSCRIBE_OPTIONS,
-       <<"http://jabber.org/protocol/pubsub#subscribe_options">>).
-
--define(NS_PUBSUB_PUBLISH_OPTIONS,
-       <<"http://jabber.org/protocol/pubsub#publish_options">>).
-
--define(NS_PUBSUB_SUB_AUTH,
-       <<"http://jabber.org/protocol/pubsub#subscribe_authorization">>).
-
--define(NS_PUBSUB_GET_PENDING,
-       <<"http://jabber.org/protocol/pubsub#get-pending">>).
-
--define(NS_COMMANDS,
-       <<"http://jabber.org/protocol/commands">>).
-
--define(NS_BYTESTREAMS,
-       <<"http://jabber.org/protocol/bytestreams">>).
-
--define(NS_ADMIN,
-       <<"http://jabber.org/protocol/admin">>).
--define(NS_ADMIN_ANNOUNCE,
-       <<"http://jabber.org/protocol/admin#announce">>).
--define(NS_ADMIN_ANNOUNCE_ALL,
-       <<"http://jabber.org/protocol/admin#announce-all">>).
--define(NS_ADMIN_SET_MOTD,
-       <<"http://jabber.org/protocol/admin#set-motd">>).
--define(NS_ADMIN_EDIT_MOTD,
-       <<"http://jabber.org/protocol/admin#edit-motd">>).
--define(NS_ADMIN_DELETE_MOTD,
-       <<"http://jabber.org/protocol/admin#delete-motd">>).
--define(NS_ADMIN_ANNOUNCE_ALLHOSTS,
-       <<"http://jabber.org/protocol/admin#announce-allhosts">>).
--define(NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS,
-       <<"http://jabber.org/protocol/admin#announce-all-allhosts">>).
--define(NS_ADMIN_SET_MOTD_ALLHOSTS,
-       <<"http://jabber.org/protocol/admin#set-motd-allhosts">>).
--define(NS_ADMIN_EDIT_MOTD_ALLHOSTS,
-       <<"http://jabber.org/protocol/admin#edit-motd-allhosts">>).
--define(NS_ADMIN_DELETE_MOTD_ALLHOSTS,
-       <<"http://jabber.org/protocol/admin#delete-motd-allhosts">>).
-
--define(NS_SERVERINFO,
-       <<"http://jabber.org/network/serverinfo">>).
-
--define(NS_RSM, <<"http://jabber.org/protocol/rsm">>).
-
--define(NS_EJABBERD_CONFIG, <<"ejabberd:config">>).
-
--define(NS_STREAM,
-       <<"http://etherx.jabber.org/streams">>).
-
--define(NS_STANZAS,
-       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>).
-
--define(NS_STREAMS,
-       <<"urn:ietf:params:xml:ns:xmpp-streams">>).
-
--define(NS_TLS, <<"urn:ietf:params:xml:ns:xmpp-tls">>).
-
--define(NS_SASL,
-       <<"urn:ietf:params:xml:ns:xmpp-sasl">>).
-
--define(NS_SESSION,
-       <<"urn:ietf:params:xml:ns:xmpp-session">>).
-
--define(NS_BIND,
-       <<"urn:ietf:params:xml:ns:xmpp-bind">>).
-
--define(NS_FEATURE_IQAUTH,
-       <<"http://jabber.org/features/iq-auth">>).
-
--define(NS_FEATURE_IQREGISTER,
-       <<"http://jabber.org/features/iq-register">>).
-
--define(NS_FEATURE_COMPRESS,
-       <<"http://jabber.org/features/compress">>).
-
--define(NS_FEATURE_MSGOFFLINE, <<"msgoffline">>).
-
--define(NS_COMPRESS,
-       <<"http://jabber.org/protocol/compress">>).
-
--define(NS_CAPS, <<"http://jabber.org/protocol/caps">>).
-
--define(NS_SHIM, <<"http://jabber.org/protocol/shim">>).
-
--define(NS_ADDRESS,
-       <<"http://jabber.org/protocol/address">>).
-
--define(NS_OOB, <<"jabber:x:oob">>).
-
--define(NS_CAPTCHA, <<"urn:xmpp:captcha">>).
-
--define(NS_MEDIA, <<"urn:xmpp:media-element">>).
-
--define(NS_BOB, <<"urn:xmpp:bob">>).
+-include("ns.hrl").
+-include("xml.hrl").
 
 -define(STANZA_ERROR(Code, Type, Condition),
        #xmlel{name = <<"error">>,
 
 -type(ljid() :: {binary(), binary(), binary()}).
 
--record(xmlel,
-{
-    name = <<"">> :: binary(),
-    attrs    = [] :: [attr()],
-    children = [] :: [xmlel() | cdata()]
-}).
-
--type(cdata() :: {xmlcdata, CData::binary()}).
-
--type(attr() :: {Name::binary(), Value::binary()}).
-
--type(xmlel() :: #xmlel{}).
-
 -record(iq, {id = <<"">>       :: binary(),
              type = get        :: get | set | result | error,
              xmlns = <<"">>    :: binary(),
diff --git a/include/logger.hrl b/include/logger.hrl
new file mode 100644 (file)
index 0000000..32e2348
--- /dev/null
@@ -0,0 +1,57 @@
+%%%----------------------------------------------------------------------
+%%%
+%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
+%%%
+%%% This program is free software; you can redistribute it and/or
+%%% modify it under the terms of the GNU General Public License as
+%%% published by the Free Software Foundation; either version 2 of the
+%%% License, or (at your option) any later version.
+%%%
+%%% This program is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%%% General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+%%% 02111-1307 USA
+%%%
+%%%----------------------------------------------------------------------
+-define(PRINT(Format, Args), io:format(Format, Args)).
+
+-ifdef(LAGER).
+-compile([{parse_transform, lager_transform}]).
+
+-define(DEBUG(Format, Args),
+       lager:debug(Format, Args)).
+
+-define(INFO_MSG(Format, Args),
+       lager:info(Format, Args)).
+
+-define(WARNING_MSG(Format, Args),
+       lager:warning(Format, Args)).
+
+-define(ERROR_MSG(Format, Args),
+       lager:error(Format, Args)).
+
+-define(CRITICAL_MSG(Format, Args),
+       lager:critical(Format, Args)).
+
+-else.
+
+-define(DEBUG(Format, Args),
+       ejabberd_logger:debug_msg(?MODULE, ?LINE, Format, Args)).
+
+-define(INFO_MSG(Format, Args),
+       ejabberd_logger:info_msg(?MODULE, ?LINE, Format, Args)).
+
+-define(WARNING_MSG(Format, Args),
+       ejabberd_logger:warning_msg(?MODULE, ?LINE, Format, Args)).
+
+-define(ERROR_MSG(Format, Args),
+       ejabberd_logger:error_msg(?MODULE, ?LINE, Format, Args)).
+
+-define(CRITICAL_MSG(Format, Args),
+       ejabberd_logger:critical_msg(?MODULE, ?LINE, Format, Args)).
+-endif.
similarity index 100%
rename from src/mod_privacy.hrl
rename to include/mod_privacy.hrl
similarity index 100%
rename from src/mod_roster.hrl
rename to include/mod_roster.hrl
diff --git a/include/ns.hrl b/include/ns.hrl
new file mode 100644 (file)
index 0000000..6d041a4
--- /dev/null
@@ -0,0 +1,146 @@
+%%%----------------------------------------------------------------------
+%%%
+%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
+%%%
+%%% This program is free software; you can redistribute it and/or
+%%% modify it under the terms of the GNU General Public License as
+%%% published by the Free Software Foundation; either version 2 of the
+%%% License, or (at your option) any later version.
+%%%
+%%% This program is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%%% General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with this program; if not, write to the Free Software
+%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+%%% 02111-1307 USA
+%%%
+%%%----------------------------------------------------------------------
+
+-define(NS_DISCO_ITEMS,
+       <<"http://jabber.org/protocol/disco#items">>).
+-define(NS_DISCO_INFO,
+       <<"http://jabber.org/protocol/disco#info">>).
+-define(NS_VCARD, <<"vcard-temp">>).
+-define(NS_VCARD_UPDATE, <<"vcard-temp:x:update">>).
+-define(NS_AUTH, <<"jabber:iq:auth">>).
+-define(NS_AUTH_ERROR, <<"jabber:iq:auth:error">>).
+-define(NS_REGISTER, <<"jabber:iq:register">>).
+-define(NS_SEARCH, <<"jabber:iq:search">>).
+-define(NS_ROSTER, <<"jabber:iq:roster">>).
+-define(NS_ROSTER_VER,
+       <<"urn:xmpp:features:rosterver">>).
+-define(NS_PRIVACY, <<"jabber:iq:privacy">>).
+-define(NS_BLOCKING, <<"urn:xmpp:blocking">>).
+-define(NS_PRIVATE, <<"jabber:iq:private">>).
+-define(NS_VERSION, <<"jabber:iq:version">>).
+-define(NS_TIME90, <<"jabber:iq:time">>).
+-define(NS_TIME, <<"urn:xmpp:time">>).
+-define(NS_LAST, <<"jabber:iq:last">>).
+-define(NS_XDATA, <<"jabber:x:data">>).
+-define(NS_IQDATA, <<"jabber:iq:data">>).
+-define(NS_DELAY91, <<"jabber:x:delay">>).
+-define(NS_DELAY, <<"urn:xmpp:delay">>).
+-define(NS_EXPIRE, <<"jabber:x:expire">>).
+-define(NS_EVENT, <<"jabber:x:event">>).
+-define(NS_CHATSTATES,
+       <<"http://jabber.org/protocol/chatstates">>).
+-define(NS_XCONFERENCE, <<"jabber:x:conference">>).
+-define(NS_STATS,
+       <<"http://jabber.org/protocol/stats">>).
+-define(NS_MUC, <<"http://jabber.org/protocol/muc">>).
+-define(NS_MUC_USER,
+       <<"http://jabber.org/protocol/muc#user">>).
+-define(NS_MUC_ADMIN,
+       <<"http://jabber.org/protocol/muc#admin">>).
+-define(NS_MUC_OWNER,
+       <<"http://jabber.org/protocol/muc#owner">>).
+-define(NS_MUC_UNIQUE,
+       <<"http://jabber.org/protocol/muc#unique">>).
+-define(NS_PUBSUB,
+       <<"http://jabber.org/protocol/pubsub">>).
+-define(NS_PUBSUB_EVENT,
+       <<"http://jabber.org/protocol/pubsub#event">>).
+-define(NS_PUBSUB_META_DATA,
+       <<"http://jabber.org/protocol/pubsub#meta-data">>).
+-define(NS_PUBSUB_OWNER,
+       <<"http://jabber.org/protocol/pubsub#owner">>).
+-define(NS_PUBSUB_NMI,
+       <<"http://jabber.org/protocol/pubsub#node-meta-info">>).
+-define(NS_PUBSUB_ERRORS,
+       <<"http://jabber.org/protocol/pubsub#errors">>).
+-define(NS_PUBSUB_NODE_CONFIG,
+       <<"http://jabber.org/protocol/pubsub#node_config">>).
+-define(NS_PUBSUB_SUB_OPTIONS,
+       <<"http://jabber.org/protocol/pubsub#subscribe_options">>).
+-define(NS_PUBSUB_SUBSCRIBE_OPTIONS,
+       <<"http://jabber.org/protocol/pubsub#subscribe_options">>).
+-define(NS_PUBSUB_PUBLISH_OPTIONS,
+       <<"http://jabber.org/protocol/pubsub#publish_options">>).
+-define(NS_PUBSUB_SUB_AUTH,
+       <<"http://jabber.org/protocol/pubsub#subscribe_authorization">>).
+-define(NS_PUBSUB_GET_PENDING,
+       <<"http://jabber.org/protocol/pubsub#get-pending">>).
+-define(NS_COMMANDS,
+       <<"http://jabber.org/protocol/commands">>).
+-define(NS_BYTESTREAMS,
+       <<"http://jabber.org/protocol/bytestreams">>).
+-define(NS_ADMIN,
+       <<"http://jabber.org/protocol/admin">>).
+-define(NS_ADMIN_ANNOUNCE,
+       <<"http://jabber.org/protocol/admin#announce">>).
+-define(NS_ADMIN_ANNOUNCE_ALL,
+       <<"http://jabber.org/protocol/admin#announce-all">>).
+-define(NS_ADMIN_SET_MOTD,
+       <<"http://jabber.org/protocol/admin#set-motd">>).
+-define(NS_ADMIN_EDIT_MOTD,
+       <<"http://jabber.org/protocol/admin#edit-motd">>).
+-define(NS_ADMIN_DELETE_MOTD,
+       <<"http://jabber.org/protocol/admin#delete-motd">>).
+-define(NS_ADMIN_ANNOUNCE_ALLHOSTS,
+       <<"http://jabber.org/protocol/admin#announce-allhosts">>).
+-define(NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS,
+       <<"http://jabber.org/protocol/admin#announce-all-allhosts">>).
+-define(NS_ADMIN_SET_MOTD_ALLHOSTS,
+       <<"http://jabber.org/protocol/admin#set-motd-allhosts">>).
+-define(NS_ADMIN_EDIT_MOTD_ALLHOSTS,
+       <<"http://jabber.org/protocol/admin#edit-motd-allhosts">>).
+-define(NS_ADMIN_DELETE_MOTD_ALLHOSTS,
+       <<"http://jabber.org/protocol/admin#delete-motd-allhosts">>).
+-define(NS_SERVERINFO,
+       <<"http://jabber.org/network/serverinfo">>).
+-define(NS_RSM, <<"http://jabber.org/protocol/rsm">>).
+-define(NS_EJABBERD_CONFIG, <<"ejabberd:config">>).
+-define(NS_STREAM,
+       <<"http://etherx.jabber.org/streams">>).
+-define(NS_STANZAS,
+       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>).
+-define(NS_STREAMS,
+       <<"urn:ietf:params:xml:ns:xmpp-streams">>).
+-define(NS_TLS, <<"urn:ietf:params:xml:ns:xmpp-tls">>).
+-define(NS_SASL,
+       <<"urn:ietf:params:xml:ns:xmpp-sasl">>).
+-define(NS_SESSION,
+       <<"urn:ietf:params:xml:ns:xmpp-session">>).
+-define(NS_BIND,
+       <<"urn:ietf:params:xml:ns:xmpp-bind">>).
+-define(NS_FEATURE_IQAUTH,
+       <<"http://jabber.org/features/iq-auth">>).
+-define(NS_FEATURE_IQREGISTER,
+       <<"http://jabber.org/features/iq-register">>).
+-define(NS_FEATURE_COMPRESS,
+       <<"http://jabber.org/features/compress">>).
+-define(NS_FEATURE_MSGOFFLINE, <<"msgoffline">>).
+-define(NS_COMPRESS,
+       <<"http://jabber.org/protocol/compress">>).
+-define(NS_CAPS, <<"http://jabber.org/protocol/caps">>).
+-define(NS_SHIM, <<"http://jabber.org/protocol/shim">>).
+-define(NS_ADDRESS,
+       <<"http://jabber.org/protocol/address">>).
+-define(NS_OOB, <<"jabber:x:oob">>).
+-define(NS_CAPTCHA, <<"urn:xmpp:captcha">>).
+-define(NS_MEDIA, <<"urn:xmpp:media-element">>).
+-define(NS_BOB, <<"urn:xmpp:bob">>).
+-define(NS_PING, <<"urn:xmpp:ping">>).
similarity index 100%
rename from src/mod_pubsub/pubsub.hrl
rename to include/pubsub.hrl
similarity index 100%
rename from src/inetrc
rename to inetrc
similarity index 100%
rename from src/install-sh
rename to install-sh
diff --git a/m4/erlang-extra.m4 b/m4/erlang-extra.m4
new file mode 100644 (file)
index 0000000..c071632
--- /dev/null
@@ -0,0 +1,82 @@
+dnl erlang-extra.m4
+
+AC_DEFUN([ERLANG_SUBST_LIB_VER],
+[AC_ERLANG_CHECK_LIB([$1])
+ERLANG_LIB_VER_SUBST="$ERLANG_LIB_VER_SUBST -e 's,[@]ERLANG_LIB_VER_$1[@],\$(ERLANG_LIB_VER_$1),g'"
+AC_SUBST([ERLANG_LIB_VER_SUBST])
+]) # ERLANG_SUBST_LIB_VER
+
+AC_DEFUN([ERLANG_VERSION_CHECK],
+[              AC_MSG_CHECKING([Erlang/OTP version])
+               cat > conftest.erl <<EOF
+-module(conftest).
+-export([[start/0]]).
+
+start() ->
+    ERTS = erlang:system_info(version),
+    RequiredMin = "$1",
+    RequiredMax = "$2",
+    Status =
+        case {string:tokens(RequiredMin, " "),
+              string:tokens(RequiredMax, " ")} of
+           {[[MinStr | _]], [[MaxStr | _]]} ->
+                case check(ERTS, {MinStr, MaxStr}) of
+                    less ->
+                         list_to_binary([[ERTS, " found, ", RequiredMin, " required"]]);
+                    greater ->
+                         list_to_binary([[ERTS, " found, ", RequiredMax, " or earlier required"]]);
+                    ok ->
+                        <<"ok">>
+                end;
+           _ ->
+               list_to_binary([[ERTS, " found, ", RequiredMin, " required"]])
+       end,
+    file:write_file("conftest.out", Status),
+    halt().
+
+check(CurStr, {MinStr, MaxStr}) ->
+    Cur = parse(CurStr),
+    Min = parse(MinStr),
+    Max = parse(MaxStr),
+    case {less_or_equal(Min, Cur), less_or_equal(Cur, Max)} of
+        {false, true} -> less;
+        {true, true} -> ok;
+        {true, false} -> greater
+    end.
+
+parse(Version) ->
+    lists:map(fun(A) -> {Int,[[]]} = string:to_integer(A), Int end,
+              string:tokens(Version, ".")).
+
+less_or_equal([[]], [[]]) ->
+    true;
+less_or_equal([[Left| Rl]], [[Right| Rr]]) ->
+    case {Left < Right, Left == Right} of
+        {true, _}  ->
+            true;
+        {false, false} ->
+            false;
+        {false, true} ->
+            less_or_equal(Rl, Rr)
+    end.
+
+EOF
+
+       $ERLC conftest.erl || AC_MSG_ERROR(["Could not compile Erlang/OTP version check program using '$ERLC'"])
+
+       if ! $ERL -s conftest -noshell -o ! -f conftest.out ; then
+          AC_MSG_ERROR(["Could not run Erlang/OTP version check program using '$ERL'"])
+       fi
+
+       if test "x`cat conftest.out`" != "xok"; then
+          AC_MSG_RESULT([failed])
+          X="`cat conftest.out`"
+          if test "[$3]" == "warn"; then
+             AC_MSG_WARN([$X])
+          else
+             AC_MSG_FAILURE([$X])
+          fi
+       else
+          AC_MSG_RESULT([ok])
+       fi
+]) dnl ERLANG_VERSION_CHECK
similarity index 100%
rename from src/msgs/ca.msg
rename to priv/msgs/ca.msg
similarity index 100%
rename from src/msgs/ca.po
rename to priv/msgs/ca.po
similarity index 100%
rename from src/msgs/cs.msg
rename to priv/msgs/cs.msg
similarity index 100%
rename from src/msgs/cs.po
rename to priv/msgs/cs.po
similarity index 100%
rename from src/msgs/de.msg
rename to priv/msgs/de.msg
similarity index 100%
rename from src/msgs/de.po
rename to priv/msgs/de.po
similarity index 100%
rename from src/msgs/ejabberd.pot
rename to priv/msgs/ejabberd.pot
similarity index 100%
rename from src/msgs/el.msg
rename to priv/msgs/el.msg
similarity index 100%
rename from src/msgs/el.po
rename to priv/msgs/el.po
similarity index 100%
rename from src/msgs/eo.msg
rename to priv/msgs/eo.msg
similarity index 100%
rename from src/msgs/eo.po
rename to priv/msgs/eo.po
similarity index 100%
rename from src/msgs/es.msg
rename to priv/msgs/es.msg
similarity index 100%
rename from src/msgs/es.po
rename to priv/msgs/es.po
similarity index 100%
rename from src/msgs/fr.msg
rename to priv/msgs/fr.msg
similarity index 100%
rename from src/msgs/fr.po
rename to priv/msgs/fr.po
similarity index 100%
rename from src/msgs/gl.msg
rename to priv/msgs/gl.msg
similarity index 100%
rename from src/msgs/gl.po
rename to priv/msgs/gl.po
similarity index 100%
rename from src/msgs/he.msg
rename to priv/msgs/he.msg
similarity index 100%
rename from src/msgs/he.po
rename to priv/msgs/he.po
similarity index 100%
rename from src/msgs/id.msg
rename to priv/msgs/id.msg
similarity index 100%
rename from src/msgs/id.po
rename to priv/msgs/id.po
similarity index 100%
rename from src/msgs/it.msg
rename to priv/msgs/it.msg
similarity index 100%
rename from src/msgs/it.po
rename to priv/msgs/it.po
similarity index 100%
rename from src/msgs/ja.msg
rename to priv/msgs/ja.msg
similarity index 100%
rename from src/msgs/ja.po
rename to priv/msgs/ja.po
similarity index 100%
rename from src/msgs/nl.msg
rename to priv/msgs/nl.msg
similarity index 100%
rename from src/msgs/nl.po
rename to priv/msgs/nl.po
similarity index 100%
rename from src/msgs/no.msg
rename to priv/msgs/no.msg
similarity index 100%
rename from src/msgs/no.po
rename to priv/msgs/no.po
similarity index 100%
rename from src/msgs/pl.msg
rename to priv/msgs/pl.msg
similarity index 100%
rename from src/msgs/pl.po
rename to priv/msgs/pl.po
similarity index 100%
rename from src/msgs/pt-br.msg
rename to priv/msgs/pt-br.msg
similarity index 100%
rename from src/msgs/pt-br.po
rename to priv/msgs/pt-br.po
similarity index 100%
rename from src/msgs/pt.msg
rename to priv/msgs/pt.msg
similarity index 100%
rename from src/msgs/pt.po
rename to priv/msgs/pt.po
similarity index 100%
rename from src/msgs/ru.msg
rename to priv/msgs/ru.msg
similarity index 100%
rename from src/msgs/ru.po
rename to priv/msgs/ru.po
similarity index 100%
rename from src/msgs/sk.msg
rename to priv/msgs/sk.msg
similarity index 100%
rename from src/msgs/sk.po
rename to priv/msgs/sk.po
similarity index 100%
rename from src/msgs/sv.msg
rename to priv/msgs/sv.msg
similarity index 100%
rename from src/msgs/sv.po
rename to priv/msgs/sv.po
similarity index 100%
rename from src/msgs/th.msg
rename to priv/msgs/th.msg
similarity index 100%
rename from src/msgs/th.po
rename to priv/msgs/th.po
similarity index 100%
rename from src/msgs/tr.msg
rename to priv/msgs/tr.msg
similarity index 100%
rename from src/msgs/tr.po
rename to priv/msgs/tr.po
similarity index 100%
rename from src/msgs/uk.msg
rename to priv/msgs/uk.msg
similarity index 100%
rename from src/msgs/uk.po
rename to priv/msgs/uk.po
similarity index 100%
rename from src/msgs/vi.msg
rename to priv/msgs/vi.msg
similarity index 100%
rename from src/msgs/vi.po
rename to priv/msgs/vi.po
similarity index 100%
rename from src/msgs/wa.msg
rename to priv/msgs/wa.msg
similarity index 100%
rename from src/msgs/wa.po
rename to priv/msgs/wa.po
similarity index 100%
rename from src/msgs/zh.msg
rename to priv/msgs/zh.msg
similarity index 100%
rename from src/msgs/zh.po
rename to priv/msgs/zh.po
diff --git a/rebar b/rebar
new file mode 100755 (executable)
index 0000000..68a96bd
Binary files /dev/null and b/rebar differ
diff --git a/rebar.config.script b/rebar.config.script
new file mode 100644 (file)
index 0000000..9ab6ef9
--- /dev/null
@@ -0,0 +1,132 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2013, Evgeniy Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created :  1 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+Cfg = case file:consult("vars.config") of
+          {ok, Terms} ->
+              Terms;
+          _Err ->
+              []
+      end,
+
+Macros = lists:flatmap(
+           fun({roster_gateway_workaround, true}) ->
+                   [{d, 'ROSTER_GATEWAY_WORKAROUND'}];
+              ({transient_supervisors, true}) ->
+                   [{d, 'NO_TRANSIENT_SUPERVISORS'}];
+              ({nif, true}) ->
+                   [{d, 'NIF'}];
+              ({db_type, mssql}) ->
+                   [{d, 'mssql'}];
+              ({lager, true}) ->
+                   [{d, 'LAGER'}];
+              (_) ->
+                   []
+           end, Cfg),
+
+DebugInfo = case lists:keysearch(debug, 1, Cfg) of
+                {value, {debug, true}} ->
+                    [debug_info];
+                _ ->
+                    []
+            end,
+
+HiPE = case lists:keysearch(hipe, 1, Cfg) of
+           {value, {hipe, true}} ->
+               [native];
+           _ ->
+               []
+       end,
+
+Includes = [{i, "include"},
+            {i, filename:join(["deps", "p1_xml", "include"])}],
+
+SrcDirs = lists:foldl(
+            fun({tools, true}, Acc) ->
+                    [tools|Acc];
+               (_, Acc) ->
+                    Acc
+            end, [], Cfg),
+
+Deps = [{p1_logger, ".*", {git, "git://github.com/processone/p1_logger"}},
+        {p1_cache_tab, ".*", {git, "git://github.com/processone/cache_tab"}},
+        {p1_tls, ".*", {git, "git://github.com/processone/tls"}},
+        {p1_stringprep, ".*", {git, "git://github.com/processone/stringprep"}},
+        {p1_xml, ".*", {git, "git://github.com/processone/xml"}},
+        {xmlrpc, ".*", {git, "git://github.com/rds13/xmlrpc"}}],
+
+ConfigureCmd = fun(Pkg, Flags) ->
+                       {'get-deps',
+                        "sh -c 'cd deps/" ++ Pkg ++
+                            " && ./configure" ++ Flags ++ "'"}
+               end,
+
+XMLFlags = lists:foldl(
+             fun({nif, true}, Acc) ->
+                     Acc ++ " --enable-nif";
+                ({full_xml, true}, Acc) ->
+                     Acc ++ " --enable-full-xml";
+                (_, Acc) ->
+                     Acc
+             end, "", Cfg),
+
+PostHooks = [ConfigureCmd("p1_tls", ""),
+             ConfigureCmd("p1_stringprep", ""),
+             ConfigureCmd("p1_xml", XMLFlags)],
+
+CfgDeps = lists:flatmap(
+            fun({mysql, true}) ->
+                    [{p1_mysql, ".*", {git, "git://github.com/processone/mysql"}}];
+               ({pgsql, true}) ->
+                    [{p1_pgsql, ".*", {git, "git://github.com/processone/pgsql"}}];
+               ({pam, true}) ->
+                    [{p1_pam, ".*", {git, "git://github.com/processone/epam"}}];
+               ({zlib, true}) ->
+                    [{p1_zlib, ".*", {git, "git://github.com/processone/zlib"}}];
+               ({stun, true}) ->
+                    [{p1_stun, ".*", {git, "git://github.com/processone/stun"}}];
+               ({json, true}) ->
+                    [{jiffy, ".*", {git, "git://github.com/davisp/jiffy"}}];
+               ({iconv, true}) ->
+                    [{p1_iconv, ".*", {git, "git://github.com/processone/eiconv"}}];
+               ({http, true}) ->
+                    [{ibrowse, ".*", {git, "git://github.com/cmullaparthi/ibrowse"}},
+                     {lhttpc, ".*", {git, "git://github.com/esl/lhttpc"}}];
+               ({lager, true}) ->
+                    [{lager, ".*", {git, "git://github.com/basho/lager"}}];
+               (_) ->
+                    []
+            end, Cfg),
+
+CfgPostHooks = lists:flatmap(
+                 fun({pam, true}) ->
+                         [ConfigureCmd("p1_pam", "")];
+                    ({zlib, true}) ->
+                         [ConfigureCmd("p1_zlib", "")];
+                    ({iconv, true}) ->
+                         [ConfigureCmd("p1_iconv", "")];
+                    (_) ->
+                         []
+                 end, Cfg),
+
+{ok, Cwd} = file:get_cwd(),
+
+Config = [{erl_opts, Includes ++ Macros ++ HiPE ++ DebugInfo ++
+               [{src_dirs, [asn1, src | SrcDirs]}]},
+          {sub_dirs, ["rel"]},
+          {ct_extra_params, "-include "
+           ++ filename:join([Cwd, "tools"]) ++ " "
+           ++ filename:join([Cwd, "deps", "p1_xml", "include"])},
+          {post_hooks, PostHooks ++ CfgPostHooks},
+          {deps, Deps ++ CfgDeps}],
+%%io:format("ejabberd configuration:~n  ~p~n", [Config]),
+Config.
+
+%% Local Variables:
+%% mode: erlang
+%% End:
+%% vim: set filetype=erlang tabstop=8:
diff --git a/rel/files/erl b/rel/files/erl
new file mode 100755 (executable)
index 0000000..6f65e3f
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+## This script replaces the default "erl" in erts-VSN/bin. This is necessary
+## as escript depends on erl and in turn, erl depends on having access to a
+## bootscript (start.boot). Note that this script is ONLY invoked as a side-effect
+## of running escript -- the embedded node bypasses erl and uses erlexec directly
+## (as it should).
+##
+## Note that this script makes the assumption that there is a start_clean.boot
+## file available in $ROOTDIR/release/VSN.
+
+# Determine the abspath of where this script is executing from.
+ERTS_BIN_DIR=$(cd ${0%/*} && pwd)
+
+# Now determine the root directory -- this script runs from erts-VSN/bin,
+# so we simply need to strip off two dirs from the end of the ERTS_BIN_DIR
+# path.
+ROOTDIR=${ERTS_BIN_DIR%/*/*}
+
+# Parse out release and erts info
+START_ERL=`cat $ROOTDIR/releases/start_erl.data`
+ERTS_VSN=${START_ERL% *}
+APP_VSN=${START_ERL#* }
+
+BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
+EMU=beam
+PROGNAME=`echo $0 | sed 's/.*\\///'`
+CMD="$BINDIR/erlexec"
+export EMU
+export ROOTDIR
+export BINDIR
+export PROGNAME
+
+exec $CMD -boot $ROOTDIR/releases/$APP_VSN/start_clean ${1+"$@"}
diff --git a/rel/files/install_upgrade.escript b/rel/files/install_upgrade.escript
new file mode 100644 (file)
index 0000000..56cea19
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/env escript
+%%! -noshell -noinput
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ft=erlang ts=4 sw=4 et
+
+-define(TIMEOUT, 60000).
+-define(INFO(Fmt,Args), io:format(Fmt,Args)).
+
+main([NodeName, Cookie, ReleasePackage]) ->
+    TargetNode = start_distribution(NodeName, Cookie),
+    {ok, Vsn} = rpc:call(TargetNode, release_handler, unpack_release,
+                         [ReleasePackage], ?TIMEOUT),
+    ?INFO("Unpacked Release ~p~n", [Vsn]),
+    {ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler,
+                                    check_install_release, [Vsn], ?TIMEOUT),
+    {ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler,
+                                    install_release, [Vsn], ?TIMEOUT),
+    ?INFO("Installed Release ~p~n", [Vsn]),
+    ok = rpc:call(TargetNode, release_handler, make_permanent, [Vsn], ?TIMEOUT),
+    ?INFO("Made Release ~p Permanent~n", [Vsn]);
+main(_) ->
+    init:stop(1).
+
+start_distribution(NodeName, Cookie) ->
+    MyNode = make_script_node(NodeName),
+    {ok, _Pid} = net_kernel:start([MyNode, shortnames]),
+    erlang:set_cookie(node(), list_to_atom(Cookie)),
+    TargetNode = make_target_node(NodeName),
+    case {net_kernel:hidden_connect_node(TargetNode),
+          net_adm:ping(TargetNode)} of
+        {true, pong} ->
+            ok;
+        {_, pang} ->
+            io:format("Node ~p not responding to pings.\n", [TargetNode]),
+            init:stop(1)
+    end,
+    TargetNode.
+
+make_target_node(Node) ->
+    [_, Host] = string:tokens(atom_to_list(node()), "@"),
+    list_to_atom(lists:concat([Node, "@", Host])).
+
+make_script_node(Node) ->
+    list_to_atom(lists:concat([Node, "_upgrader_", os:getpid()])).
diff --git a/rel/reltool.config.script b/rel/reltool.config.script
new file mode 100644 (file)
index 0000000..a52df7b
--- /dev/null
@@ -0,0 +1,104 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2013, Evgeniy Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created :  8 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+Vars = case file:consult(filename:join(["..", "vars.config"])) of
+           {ok, Terms} ->
+               Terms;
+           _Err ->
+               []
+       end,
+
+RequiredOTPApps = [sasl, crypto, public_key, ssl,
+                   mnesia, inets, compiler],
+
+ConfiguredOTPApps = lists:flatmap(
+                      fun({tools, true}) ->
+                              [tools, runtime_tools];
+                         (_) ->
+                              []
+                      end, Vars),
+
+OTPApps = RequiredOTPApps ++ ConfiguredOTPApps,
+
+DepRequiredApps = [p1_logger, p1_cache_tab, p1_tls, p1_stringprep, p1_xml, xmlrpc],
+
+DepConfiguredApps = lists:flatmap(
+                      fun({mysql, true}) -> [p1_mysql];
+                         ({pgsql, true}) -> [p1_pgsql];
+                         ({pam, true}) -> [p1_pam];
+                         ({zlib, true}) -> [p1_zlib];
+                         ({stun, true}) -> [p1_stun];
+                         ({json, true}) -> [jiffy];
+                         ({iconv, true}) -> [p1_iconv];
+                         ({http, true}) -> [ibrowse, lhttpc];
+                         ({odbc, true}) -> [odbc];
+                         (_) -> []
+                      end, Vars),
+
+DepApps = DepRequiredApps ++ DepConfiguredApps,
+
+Sys = [{lib_dirs, []},
+       {erts, [{mod_cond, derived}, {app_file, strip}]},
+       {app_file, strip},
+       {rel, "ejabberd", proplists:get_value(vsn, Vars),
+        [
+         kernel,
+         stdlib,
+         ejabberd
+        ] ++ OTPApps ++ DepApps},
+       {rel, "start_clean", "",
+        [
+         kernel,
+         stdlib
+        ]},
+       {boot_rel, "ejabberd"},
+       {profile, embedded},
+       {incl_cond, exclude},
+       {excl_archive_filters, [".*"]}, %% Do not archive built libs
+       {excl_sys_filters, ["^bin/.*", "^erts.*/bin/(dialyzer|typer)",
+                           "^erts.*/(doc|info|include|lib|man|src)"]},
+       {excl_app_filters, ["\.gitignore"]},
+       {app, stdlib, [{incl_cond, include}]},
+       {app, kernel, [{incl_cond, include}]},
+       {app, ejabberd, [{incl_cond, include}, {lib_dir, ".."}]}]
+++ lists:map(
+     fun(App) ->
+             {app, App, [{incl_cond, include},
+                         {lib_dir, "../deps/" ++ atom_to_list(App)}]}
+     end, DepApps)
+++ lists:map(
+     fun(App) ->
+             {app, App, [{incl_cond, include}]}
+     end, OTPApps).
+
+Overlay = [
+           {mkdir, "var/log/ejabberd"},
+           {mkdir, "var/lock"},
+           {mkdir, "var/lib/ejabberd"},
+           {mkdir, "etc/ejabberd"},
+           {mkdir, "doc"},
+           {template, "files/erl", "\{\{erts_vsn\}\}/bin/erl"},
+           {template, "../ejabberdctl.template", "bin/ejabberdctl"},
+           {copy, "../ejabberdctl.cfg.example", "etc/ejabberd/ejabberdctl.cfg"},
+           {copy, "../ejabberd.cfg.example", "etc/ejabberd/ejabberd.cfg"},
+           {copy, "../inetrc", "etc/ejabberd/inetrc"},
+           {copy, "files/install_upgrade.escript", "bin/install_upgrade.escript"}
+          ],
+
+Config = [{sys, Sys},
+          {overlay_vars, "../vars.config"},
+          {target_dir, "ejabberd"},
+          {overlay, Overlay}],
+
+%%io:format("ejabberd release:~n  ~p~n", [Config]),
+Config.
+
+%% Local Variables:
+%% mode: erlang
+%% End:
+%% vim: set filetype=erlang tabstop=8:
similarity index 100%
rename from src/odbc/mssql2000.sql
rename to sql/mssql2000.sql
similarity index 100%
rename from src/odbc/mssql2005.sql
rename to sql/mssql2005.sql
similarity index 100%
rename from src/odbc/mysql.sql
rename to sql/mysql.sql
similarity index 100%
rename from src/odbc/pg.sql
rename to sql/pg.sql
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644 (file)
index b5fd9a2..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-EXPAT_CFLAGS = @EXPAT_CFLAGS@
-ERLANG_CFLAGS= @ERLANG_CFLAGS@
-
-EXPAT_LIBS = @EXPAT_LIBS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj
-
-INSTALLUSER=@INSTALLUSER@
-# if no user was enabled, don't set privileges or ownership
-ifeq ($(INSTALLUSER),)
-  O_USER=
-  G_USER=
-  CHOWN_COMMAND=echo
-  CHOWN_OUTPUT=/dev/null
-  INIT_USER=root
-else
-  O_USER=-o $(INSTALLUSER)
-  G_USER=-g $(INSTALLUSER)
-  CHOWN_COMMAND=chown
-  CHOWN_OUTPUT=&1
-  INIT_USER=$(INSTALLUSER)
-endif
-
-EFLAGS += -pa .
-ERLANG_CFLAGS +=
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-  EFLAGS+=+debug_info
-endif
-
-DEBUGTOOLS = p1_prof.erl
-ifdef debugtools
-  SOURCES+=$(DEBUGTOOLS)
-endif
-
-ifeq (@hipe@, true)
-  EFLAGS+=+native
-endif
-
-ifeq (@roster_gateway_workaround@, true)
-  EFLAGS+=-DROSTER_GATEWAY_WORKAROUND
-endif
-
-ifeq (@full_xml@, true)
-  EFLAGS+=-DFULL_XML_SUPPORT
-endif
-
-ifeq (@nif@, true)
-  EFLAGS+=-DNIF
-  ERLSHLIBS=xml.so
-endif
-
-ifeq (@transient_supervisors@, false)
-  EFLAGS+=-DNO_TRANSIENT_SUPERVISORS
-endif
-
-ifeq (@md2@, true)
-  EFLAGS+=-DHAVE_MD2
-  ERLANG_CFLAGS += -DHAVE_MD2
-endif
-
-INSTALL_EPAM=
-ifeq (@pam@, pam)
-  INSTALL_EPAM=install -m 750 $(O_USER) epam $(PBINDIR)
-endif
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ mysql pgsql stringprep stun @tls@ @odbc@ @ejabberd_zlib@
-ERLSHLIBS += expat_erl.so
-ERLBEHAVS = cyrsasl.erl gen_mod.erl p1_fsm.erl ejabberd_auth.erl
-SOURCES_ALL = $(wildcard *.erl)
-SOURCES_MISC = $(ERLBEHAVS) $(DEBUGTOOLS)
-SOURCES += $(filter-out $(SOURCES_MISC),$(SOURCES_ALL))
-ERLBEHAVBEAMS = $(ERLBEHAVS:.erl=.beam)
-BEAMS = $(SOURCES:.erl=.beam)
-
-DESTDIR =
-
-# /etc/ejabberd/
-ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
-
-# /sbin/
-SBINDIR = $(DESTDIR)@sbindir@
-
-# /lib/ejabberd/
-EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd
-
-# /share/doc/ejabberd
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-datarootdir = @datarootdir@
-DOCDIR = $(DESTDIR)@docdir@
-
-# /usr/lib/ejabberd/ebin/
-BEAMDIR = $(EJABBERDDIR)/ebin
-
-# /usr/lib/ejabberd/include/
-INCLUDEDIR = $(EJABBERDDIR)/include
-
-# /usr/lib/ejabberd/priv/
-PRIVDIR = $(EJABBERDDIR)/priv
-
-# /usr/lib/ejabberd/priv/bin
-PBINDIR = $(PRIVDIR)/bin
-
-# /usr/lib/ejabberd/priv/lib
-SODIR = $(PRIVDIR)/lib
-
-# /usr/lib/ejabberd/priv/msgs
-MSGSDIR = $(PRIVDIR)/msgs
-
-# /var/lib/ejabberd/
-SPOOLDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
-
-# /var/lock/ejabberdctl
-CTLLOCKDIR = $(DESTDIR)@localstatedir@/lock/ejabberdctl
-
-# /var/lib/ejabberd/.erlang.cookie
-COOKIEFILE = $(SPOOLDIR)/.erlang.cookie
-
-# /var/log/ejabberd/
-LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
-
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-ifeq ($(shell uname),Darwin)
-    DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-endif
-ifeq ($(shell uname),SunOs)
-    DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
-endif
-
-all: $(ERLSHLIBS) compile-beam all-recursive
-
-compile-beam: XmppAddr.hrl $(ERLBEHAVBEAMS) $(BEAMS)
-
-$(BEAMS): $(ERLBEHAVBEAMS)
-
-all-recursive: $(ERLBEHAVBEAMS)
-
-%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) $<
-
-
-all-recursive install-recursive uninstall-recursive \
-clean-recursive distclean-recursive \
-mostlyclean-recursive maintainer-clean-recursive:
-       @subdirs="$(SUBDIRS)"; for subdir in $$subdirs; do \
-       target=`echo $@|sed 's,-recursive,,'`; \
-       echo making $$target in $$subdir; \
-       (cd $$subdir && $(MAKE) $$target) || exit 1; \
-       done
-
-
-%.hrl: %.asn1
-       @ERLC@ $(ASN_FLAGS) $<
-       @ERLC@ -W $(EFLAGS) $*.erl
-
-$(ERLSHLIBS):  %.so:   %.c
-       $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) \
-               $(subst ../,,$(subst .so,.c,$@)) \
-               $(EXPAT_LIBS) \
-               $(EXPAT_CFLAGS) \
-               $(ERLANG_LIBS) \
-               $(ERLANG_CFLAGS) \
-               -o $@ \
-               $(DYNAMIC_LIB_CFLAGS)
-
-translations:
-       ../contrib/extract_translations/prepare-translation.sh -updateall
-
-install: all
-       #
-       # Configuration files
-       install -d -m 750 $(G_USER) $(ETCDIR)
-       [ -f $(ETCDIR)/ejabberd.cfg ] \
-               && install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new \
-               || install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
-       sed -e "s*@rootdir@*@prefix@*" \
-               -e "s*@installuser@*@INSTALLUSER@*" \
-               -e "s*@LIBDIR@*@libdir@*" \
-               -e "s*@SYSCONFDIR@*@sysconfdir@*" \
-               -e "s*@LOCALSTATEDIR@*@localstatedir@*" \
-               -e "s*@DOCDIR@*@docdir@*" \
-               -e "s*@erl@*@ERL@*" ejabberdctl.template \
-               > ejabberdctl.example
-       [ -f $(ETCDIR)/ejabberdctl.cfg ] \
-               && install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new \
-               || install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
-       [ -f $(ETCDIR)/inetrc ] \
-               && install -b -m 644 $(G_USER) inetrc $(ETCDIR)/inetrc-new \
-               || install -b -m 644 $(G_USER) inetrc $(ETCDIR)/inetrc
-       #
-       # Administration script
-       [ -d $(SBINDIR) ] || install -d -m 755 $(SBINDIR)
-       install -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
-       #
-       # Init script
-       sed -e "s*@ctlscriptpath@*$(SBINDIR)*" \
-               -e "s*@installuser@*$(INIT_USER)*" ejabberd.init.template \
-               > ejabberd.init
-       chmod 755 ejabberd.init
-       #
-       # Binary Erlang files
-       install -d $(BEAMDIR)
-       install -m 644 *.app $(BEAMDIR)
-       install -m 644 *.beam $(BEAMDIR)
-       rm -f $(BEAMDIR)/configure.beam
-       #
-       # ejabberd header files
-       install -d $(INCLUDEDIR)
-       install -m 644 *.hrl $(INCLUDEDIR)
-       install -d $(INCLUDEDIR)/eldap/
-       install -m 644 eldap/*.hrl $(INCLUDEDIR)/eldap/
-       install -d $(INCLUDEDIR)/mod_muc/
-       install -m 644 mod_muc/*.hrl $(INCLUDEDIR)/mod_muc/
-       install -d $(INCLUDEDIR)/mod_proxy65/
-       install -m 644 mod_proxy65/*.hrl $(INCLUDEDIR)/mod_proxy65/
-       install -d $(INCLUDEDIR)/mod_pubsub/
-       install -m 644 mod_pubsub/*.hrl $(INCLUDEDIR)/mod_pubsub/
-       install -d $(INCLUDEDIR)/web/
-       install -m 644 web/*.hrl $(INCLUDEDIR)/web/
-       #
-       # Binary C programs
-       install -d $(PBINDIR)
-       install -m 750 $(O_USER) ../tools/captcha.sh $(PBINDIR)
-       $(INSTALL_EPAM)
-       #
-       # Binary system libraries
-       install -d $(SODIR)
-       install -m 644 *.so $(SODIR)
-       #
-       # Translated strings
-       install -d $(MSGSDIR)
-       install -m 644 msgs/*.msg $(MSGSDIR)
-       #
-       # Spool directory
-       install -d -m 750 $(O_USER) $(SPOOLDIR)
-       $(CHOWN_COMMAND) -R @INSTALLUSER@ $(SPOOLDIR) >$(CHOWN_OUTPUT)
-       chmod -R 750 $(SPOOLDIR)
-       [ ! -f $(COOKIEFILE) ] || { $(CHOWN_COMMAND) @INSTALLUSER@ $(COOKIEFILE) >$(CHOWN_OUTPUT) ; chmod 400 $(COOKIEFILE) ; }
-       #
-       # ejabberdctl lock directory
-       install -d -m 750 $(O_USER) $(CTLLOCKDIR)
-       $(CHOWN_COMMAND) -R @INSTALLUSER@ $(CTLLOCKDIR) >$(CHOWN_OUTPUT)
-       chmod -R 750 $(CTLLOCKDIR)
-       #
-       # Log directory
-       install -d -m 750 $(O_USER) $(LOGDIR)
-       $(CHOWN_COMMAND) -R @INSTALLUSER@ $(LOGDIR) >$(CHOWN_OUTPUT)
-       chmod -R 750 $(LOGDIR)
-       #
-       # Documentation
-       install -d $(DOCDIR)
-       install -m 644 ../doc/dev.html $(DOCDIR)
-       install -m 644 ../doc/guide.html $(DOCDIR)
-       install -m 644 ../doc/*.png $(DOCDIR)
-       install -m 644 ../doc/*.txt $(DOCDIR)
-       [ -f ../doc/guide.pdf ] \
-               && install -m 644 ../doc/guide.pdf $(DOCDIR) \
-               || echo "No ../doc/guide.pdf was built"
-       install -m 644 ../COPYING $(DOCDIR)
-
-uninstall: uninstall-binary
-
-uninstall-binary:
-       rm -f  $(SBINDIR)/ejabberdctl
-       rm -fr $(DOCDIR)
-       rm -f  $(BEAMDIR)/*.beam
-       rm -f  $(BEAMDIR)/*.app
-       rm -fr $(BEAMDIR)
-       rm -f  $(INCLUDEDIR)/*.hrl
-       rm -fr $(INCLUDEDIR)
-       rm -fr $(PBINDIR)
-       rm -f  $(SODIR)/*.so
-       rm -fr $(SODIR)
-       rm -f  $(MSGSDIR)/*.msgs
-       rm -fr $(MSGSDIR)
-       rm -fr $(PRIVDIR)
-       rm -fr $(EJABBERDDIR)
-
-uninstall-all: uninstall-binary
-       rm -rf $(ETCDIR)
-       rm -rf $(EJABBERDDIR)
-       rm -rf $(SPOOLDIR)
-       rm -rf $(CTLLOCKDIR)
-       rm -rf $(LOGDIR)
-
-clean: clean-recursive clean-local
-
-clean-local:
-       rm -f *.beam $(ERLSHLIBS) epam ejabberdctl.example
-       rm -f XmppAddr.asn1db XmppAddr.erl XmppAddr.hrl
-
-distclean: distclean-recursive clean-local
-       rm -f config.status
-       rm -f config.log
-       rm -f Makefile
-       [ ! -f ../ChangeLog ] || rm -f ../ChangeLog
-
-TAGS:
-       etags *.erl
-
-Makefile: Makefile.in
-
-dialyzer: $(BEAMS)
-       @dialyzer -c .
diff --git a/src/acinclude.m4 b/src/acinclude.m4
deleted file mode 100644 (file)
index 79c226a..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-AC_DEFUN([AM_WITH_EXPAT],
-[ AC_ARG_WITH(expat,
-             [AC_HELP_STRING([--with-expat=PREFIX], [prefix where EXPAT is installed])])
-
-  EXPAT_CFLAGS=
-  EXPAT_LIBS=
-       if test x"$with_expat" != x; then
-               EXPAT_CFLAGS="-I$with_expat/include"
-               EXPAT_LIBS="-L$with_expat/lib"
-       fi
-
-       AC_CHECK_LIB(expat, XML_ParserCreate,
-                    [ EXPAT_LIBS="$EXPAT_LIBS -lexpat"
-                      expat_found=yes ],
-                    [ expat_found=no ],
-                    "$EXPAT_LIBS")
-       if test $expat_found = no; then
-               AC_MSG_ERROR([Could not find development files of Expat library])
-       fi
-       expat_save_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS $EXPAT_CFLAGS"
-       expat_save_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $EXPAT_CFLAGS"
-       AC_CHECK_HEADERS(expat.h, , expat_found=no)
-       if test $expat_found = no; then
-               AC_MSG_ERROR([Could not find expat.h])
-       fi
-       CFLAGS="$expat_save_CFLAGS"
-       CPPFLAGS="$expat_save_CPPFLAGS"
-
-  AC_SUBST(EXPAT_CFLAGS)
-  AC_SUBST(EXPAT_LIBS)
-])
-
-AC_DEFUN([AM_WITH_ZLIB],
-[ AC_ARG_WITH(zlib,
-             [AC_HELP_STRING([--with-zlib=PREFIX], [prefix where zlib is installed])])
-
-if test x"$ejabberd_zlib" != x; then
-  ZLIB_CFLAGS=
-  ZLIB_LIBS=
-       if test x"$with_zlib" != x; then
-               ZLIB_CFLAGS="-I$with_zlib/include"
-               ZLIB_LIBS="-L$with_zlib/lib"
-       fi
-
-       AC_CHECK_LIB(z, gzgets,
-                    [ ZLIB_LIBS="$ZLIB_LIBS -lz"
-                      zlib_found=yes ],
-                    [ zlib_found=no ],
-                    "$ZLIB_LIBS")
-       if test $zlib_found = no; then
-               AC_MSG_ERROR([Could not find development files of zlib library. Install them or disable `ejabberd_zlib' with: --disable-ejabberd_zlib])
-       fi
-       zlib_save_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS $ZLIB_CFLAGS"
-       zlib_save_CPPFLAGS="$CFLAGS"
-       CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS"
-       AC_CHECK_HEADERS(zlib.h, , zlib_found=no)
-       if test $zlib_found = no; then
-               AC_MSG_ERROR([Could not find zlib.h. Install it or disable `ejabberd_zlib' with: --disable-ejabberd_zlib])
-       fi
-       CFLAGS="$zlib_save_CFLAGS"
-       CPPFLAGS="$zlib_save_CPPFLAGS"
-
-  AC_SUBST(ZLIB_CFLAGS)
-  AC_SUBST(ZLIB_LIBS)
-fi
-])
-
-AC_DEFUN([AM_WITH_PAM],
-[ AC_ARG_WITH(pam,
-             [AC_HELP_STRING([--with-pam=PREFIX], [prefix where PAM is installed])])
-if test x"$pam" != x; then
-  PAM_CFLAGS=
-  PAM_LIBS=
-       if test x"$with_pam" != x; then
-               PAM_CFLAGS="-I$with_pam/include"
-               PAM_LIBS="-L$with_pam/lib"
-       fi
-
-       AC_CHECK_LIB(pam, pam_start,
-                    [ PAM_LIBS="$PAM_LIBS -lpam"
-                      pam_found=yes ],
-                    [ pam_found=no ],
-                    "$PAM_LIBS")
-       if test $pam_found = no; then
-               AC_MSG_ERROR([Could not find development files of PAM library. Install them or disable `pam' with: --disable-pam])
-       fi
-       pam_save_CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS $PAM_CFLAGS"
-       pam_save_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $PAM_CFLAGS"
-       AC_CHECK_HEADERS(security/pam_appl.h, , pam_found=no)
-       if test $pam_found = no; then
-               AC_MSG_ERROR([Could not find security/pam_appl.h. Install it or disable `pam' with: --disable-pam])
-       fi
-       CFLAGS="$pam_save_CFLAGS"
-       CPPFLAGS="$pam_save_CPPFLAGS"
-
-  AC_SUBST(PAM_CFLAGS)
-  AC_SUBST(PAM_LIBS)
-fi
-])
-
-AC_DEFUN([AM_WITH_ERLANG],
-[ AC_ARG_WITH(erlang,
-             [AC_HELP_STRING([--with-erlang=PREFIX], [path to erlc and erl])])
-
-   AC_PATH_TOOL(ERLC, erlc, , $with_erlang:$with_erlang/bin:$PATH)
-   AC_PATH_TOOL(ERL, erl, , $with_erlang:$with_erlang/bin:$PATH)
-
-   if test "z$ERLC" = "z" || test "z$ERL" = "z"; then
-               AC_MSG_ERROR([erlang not found])
-   fi
-
-
-   cat >>conftest.erl <<_EOF
-
--module(conftest).
--author('alexey@sevcom.net').
-
--export([[start/0]]).
-
-start() ->
-    EIDirS = code:lib_dir("erl_interface") ++ "\n",
-    EILibS =  libpath("erl_interface") ++ "\n",
-    RootDirS = code:root_dir() ++ "\n",
-    file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ RootDirS)),
-    halt().
-
-%% return physical architecture based on OS/Processor
-archname() ->
-    ArchStr = erlang:system_info(system_architecture),
-    case os:type() of
-       {win32, _} -> "windows";
-       {unix,UnixName} ->
-           Specs = string:tokens(ArchStr,"-"),
-           Cpu = case lists:nth(2,Specs) of
-                     "pc" -> "x86";
-                     _ -> hd(Specs)
-                 end,
-           atom_to_list(UnixName) ++ "-" ++ Cpu;
-       _ -> "generic"
-    end.
-
-%% Return arch-based library path or a default value if this directory
-%% does not exist
-libpath(App) ->
-    PrivDir    = code:priv_dir(App),
-    ArchDir    = archname(),
-    LibArchDir = filename:join([[PrivDir,"lib",ArchDir]]),
-    case file:list_dir(LibArchDir) of
-       %% Arch lib dir exists: We use it
-       {ok, _List}  -> LibArchDir;
-       %% Arch lib dir does not exist: Return the default value
-       %% ({error, enoent}):
-       _Error -> code:lib_dir("erl_interface") ++ "/lib"
-    end.
-
-_EOF
-
-   if ! $ERLC conftest.erl; then
-          AC_MSG_ERROR([could not compile sample program])
-   fi
-
-   if ! $ERL -s conftest -noshell; then
-       AC_MSG_ERROR([could not run sample program])
-   fi
-
-   if ! test -f conftest.out; then
-       AC_MSG_ERROR([erlang program was not properly executed, (conftest.out was not produced)])
-   fi
-
-   # First line
-   ERLANG_EI_DIR=`cat conftest.out | head -n 1`
-   # Second line
-   ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
-   # End line
-   ERLANG_DIR=`cat conftest.out | tail -n 1`
-
-   ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include"
-   ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei"
-
-   AC_SUBST(ERLANG_CFLAGS)
-   AC_SUBST(ERLANG_LIBS)
-   AC_SUBST(ERLC)
-   AC_SUBST(ERL)
-])
-
-AC_DEFUN([AC_MOD_ENABLE],
-[
-$1=
-make_$1=
-AC_MSG_CHECKING([whether build $1])
-AC_ARG_ENABLE($1,
-  [AC_HELP_STRING([--enable-$1], [enable $1 (default: $2)])],
-    [mr_enable_$1="$enableval"],
-     [mr_enable_$1=$2])
-if test "$mr_enable_$1" = "yes"; then
-$1=$1
-make_$1=$1/Makefile
-fi
-AC_MSG_RESULT($mr_enable_$1)
-AC_SUBST($1)
-AC_SUBST(make_$1)
-
-])
-
-
-dnl From Bruno Haible.
-
-AC_DEFUN([AM_ICONV],
-[
-  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
-  dnl those with the standalone portable GNU libiconv installed).
-  AC_ARG_WITH([libiconv-prefix],
-   [AC_HELP_STRING([--with-libiconv-prefix=PREFIX], [prefix where libiconv is installed])], [
-    for dir in `echo "$withval" | tr : ' '`; do
-      if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
-      if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
-      if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi
-    done
-   ])
-
-  AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
-    am_cv_func_iconv="no, consider installing GNU libiconv"
-    am_cv_lib_iconv=no
-    AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
-     [iconv_t cd = iconv_open("","");
-       iconv(cd,NULL,NULL,NULL,NULL);
-       iconv_close(cd);],
-       am_cv_func_iconv=yes)
-    if test "$am_cv_func_iconv" != yes; then
-      am_save_LIBS="$LIBS"
-      LIBS="$LIBS -liconv"
-      AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
-        [iconv_t cd = iconv_open("","");
-         iconv(cd,NULL,NULL,NULL,NULL);
-         iconv_close(cd);],
-        am_cv_lib_iconv=yes
-        am_cv_func_iconv=yes)
-      LIBS="$am_save_LIBS"
-    fi
-       dnl trying /usr/local
-    if test "$am_cv_func_iconv" != yes; then
-      am_save_LIBS="$LIBS"
-         am_save_CFLAGS="$CFLAGS"
-         am_save_LDFLAGS="$LDFLAGS"
-      LIBS="$LIBS -liconv"
-         LDFLAGS="$LDFLAGS -L/usr/local/lib"
-         CFLAGS="$CFLAGS -I/usr/local/include"
-      AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
-        [iconv_t cd = iconv_open("","");
-         iconv(cd,NULL,NULL,NULL,NULL);
-         iconv_close(cd);],
-        am_cv_lib_iconv=yes
-        am_cv_func_iconv=yes
-               CPPFLAGS="$CPPFLAGS -I/usr/local/include",
-               LDFLAGS="$am_save_LDFLAGS"
-               CFLAGS="$am_save_CFLAGS")
-      LIBS="$am_save_LIBS"
-    fi
-
-  ])
-  if test "$am_cv_func_iconv" = yes; then
-    AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
-    AC_MSG_CHECKING([for iconv declaration])
-    AC_CACHE_VAL(am_cv_proto_iconv, [
-      AC_TRY_COMPILE([
-#include <stdlib.h>
-#include <iconv.h>
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
-], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
-      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
-    am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
-    AC_MSG_RESULT([$]{ac_t:-
-         }[$]am_cv_proto_iconv)
-    AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
-      [Define as const if the declaration of iconv() needs const.])
-  fi
-  LIBICONV=
-  if test "$am_cv_lib_iconv" = yes; then
-    LIBICONV="-liconv"
-  fi
-  AC_SUBST(LIBICONV)
-])
-
-dnl <openssl>
-AC_DEFUN([AM_WITH_OPENSSL],
-[ AC_ARG_WITH(openssl,
-      [AC_HELP_STRING([--with-openssl=PREFIX], [prefix where OPENSSL is installed])])
-unset SSL_LIBS;
-unset SSL_CFLAGS;
-have_openssl=no
-if test x"$tls" != x; then
-    for ssl_prefix in $withval /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do
-        printf "looking for openssl in $ssl_prefix...\n"
-        SSL_CFLAGS="-I$ssl_prefix/include"
-        SSL_LIBS="-L$ssl_prefix/lib -lcrypto"
-        AC_CHECK_LIB(ssl, SSL_new, [ have_openssl=yes ], [ have_openssl=no ], [ $SSL_LIBS $SSL_CFLAGS ])
-        if test x"$have_openssl" = xyes; then
-            save_CPPFLAGS=$CPPFLAGS
-            CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS"
-            AC_CHECK_HEADERS(openssl/ssl.h, have_openssl_h=yes)
-            CPPFLAGS=$save_CPPFLAGS
-            if test x"$have_openssl_h" = xyes; then
-                have_openssl=yes
-                printf "openssl found in $ssl_prefix\n";
-                SSL_LIBS="-L$ssl_prefix/lib -lssl -lcrypto"
-                CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS"
-                SSL_CFLAGS="-DHAVE_SSL"
-                break
-            fi
-       else
-           # Clear this from the autoconf cache, so in the next pass of
-           # this loop with different -L arguments, it will test again.
-           unset ac_cv_lib_ssl_SSL_new
-        fi
-    done
-if test x${have_openssl} != xyes; then
-    AC_MSG_ERROR([Could not find development files of OpenSSL library. Install them or disable `tls' with: --disable-tls])
-fi
-AC_SUBST(SSL_LIBS)
-AC_SUBST(SSL_CFLAGS)
-fi
-])
-dnl <openssl/>
index 77c55e79dd55e4ee2cf7313bd4b3b5f2e7922e4a..88e6f6884f6d1a78a55734805f03bc2a263dc984 100644 (file)
@@ -32,6 +32,7 @@
         match_rule/3, match_acl/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 
 -record(acl, {aclname, aclspec}).
index 6af65e5d16c129b75a0bf60da2fa1c0668ed2874..50ef7e5bf208b88a44f4405948946c642ca53c27 100644 (file)
@@ -35,6 +35,7 @@
 ]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 -include("adhoc.hrl").
 
diff --git a/src/cache_tab.erl b/src/cache_tab.erl
deleted file mode 100644 (file)
index 95343e4..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : cache_tab.erl
-%%% Author  : Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%% Description : Caching key-value table
-%%%
-%%% Created : 29 Aug 2010 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%-------------------------------------------------------------------
--module(cache_tab).
-
--define(GEN_SERVER, gen_server).
-
--behaviour(?GEN_SERVER).
-
-%% API
--export([start_link/4, new/2, delete/1, delete/3, lookup/3,
-        insert/4, info/2, tab2list/1, setopts/2,
-        dirty_lookup/3, dirty_insert/4, dirty_delete/3,
-        all/0, test/0]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
-        terminate/2, code_change/3]).
-
--include("ejabberd.hrl").
-
--record(state, {tab = treap:empty(),
-               name,
-               size = 0,
-               owner,
-               max_size,
-               life_time,
-               warn,
-               hits = 0,
-               miss = 0,
-               procs_num,
-               cache_missed,
-               lru,
-               shrink_size}).
-
--define(PROCNAME, ?MODULE).
--define(CALL_TIMEOUT, 60000).
-
-%% Defaults
--define(MAX_SIZE, 1000).
--define(WARN, true).
--define(CACHE_MISSED, true).
--define(LRU, true).
--define(LIFETIME, 600). %% 10 minutes
-
-%%====================================================================
-%% API
-%%====================================================================
-start_link(Proc, Tab, Opts, Owner) ->
-    ?GEN_SERVER:start_link(
-      {local, Proc}, ?MODULE, [Tab, Opts, get_proc_num(), Owner], []).
-
-new(Tab, Opts) ->
-    Res = lists:flatmap(
-           fun(Proc) ->
-                   Spec = {{Tab, Proc},
-                           {?MODULE, start_link,
-                            [Proc, Tab, Opts, self()]},
-                           permanent,
-                           brutal_kill,
-                           worker,
-                           [?MODULE]},
-                   case supervisor:start_child(cache_tab_sup, Spec) of
-                       {ok, _Pid} ->
-                           [ok];
-                       R ->
-                           [R]
-                   end
-           end, get_all_procs(Tab)),
-    case lists:filter(fun(ok) -> false; (_) -> true end, Res) of
-       [] ->
-           ok;
-       Err ->
-           {error, Err}
-    end.
-
-delete(Tab) ->
-    lists:foreach(
-      fun(Proc) ->
-             supervisor:terminate_child(cache_tab_sup, {Tab, Proc}),
-             supervisor:delete_child(cache_tab_sup, {Tab, Proc})
-      end, get_all_procs(Tab)).
-
-delete(Tab, Key, F) ->
-    ?GEN_SERVER:call(
-       get_proc_by_hash(Tab, Key), {delete, Key, F}, ?CALL_TIMEOUT).
-
-dirty_delete(Tab, Key, F) ->
-    F(),
-    ?GEN_SERVER:call(
-       get_proc_by_hash(Tab, Key), {cache_delete, Key}, ?CALL_TIMEOUT).
-
-lookup(Tab, Key, F) ->
-    ?GEN_SERVER:call(
-       get_proc_by_hash(Tab, Key), {lookup, Key, F}, ?CALL_TIMEOUT).
-
-dirty_lookup(Tab, Key, F) ->
-    Proc = get_proc_by_hash(Tab, Key),
-    case ?GEN_SERVER:call(Proc, {cache_lookup, Key}, ?CALL_TIMEOUT) of
-       {ok, '$cached_mismatch'} ->
-           error;
-       {ok, Val} ->
-           {ok, Val};
-       _ ->
-           {Result, NewVal} = case F() of
-                                  {ok, Val} ->
-                                      {{ok, Val}, Val};
-                                  _ ->
-                                      {error, '$cached_mismatch'}
-                              end,
-           ?GEN_SERVER:call(
-              Proc, {cache_insert, Key, NewVal}, ?CALL_TIMEOUT),
-           Result
-    end.
-
-insert(Tab, Key, Val, F) ->
-    ?GEN_SERVER:call(
-       get_proc_by_hash(Tab, Key), {insert, Key, Val, F}, ?CALL_TIMEOUT).
-
-dirty_insert(Tab, Key, Val, F) ->
-    F(),
-    ?GEN_SERVER:call(
-       get_proc_by_hash(Tab, Key), {cache_insert, Key, Val}, ?CALL_TIMEOUT).
-
-info(Tab, Info) ->
-    case lists:map(
-          fun(Proc) ->
-                  ?GEN_SERVER:call(Proc, {info, Info}, ?CALL_TIMEOUT)
-          end, get_all_procs(Tab)) of
-       Res when Info == size ->
-           {ok, lists:sum(Res)};
-       Res when Info == all ->
-           {ok, Res};
-       Res when Info == ratio ->
-           {H, M} = lists:foldl(
-                      fun({Hits, Miss}, {HitsAcc, MissAcc}) ->
-                              {HitsAcc + Hits, MissAcc + Miss}
-                      end, {0, 0}, Res),
-           {ok, [{hits, H}, {miss, M}]};
-       _ ->
-           {error, badarg}
-    end.
-
-setopts(Tab, Opts) ->
-    lists:foreach(
-      fun(Proc) ->
-             ?GEN_SERVER:call(Proc, {setopts, Opts}, ?CALL_TIMEOUT)
-      end, get_all_procs(Tab)).
-
-tab2list(Tab) ->
-    lists:flatmap(
-      fun(Proc) ->
-             ?GEN_SERVER:call(Proc, tab2list, ?CALL_TIMEOUT)
-      end, get_all_procs(Tab)).
-
-all() ->
-    lists:usort(
-      [Tab || {{Tab, _}, _, _, _} <- supervisor:which_children(cache_tab_sup)]).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-init([Tab, Opts, N, Pid]) ->
-    State = #state{procs_num = N,
-                  owner = Pid,
-                  name = Tab},
-    {ok, do_setopts(State, Opts)}.
-
-handle_call({lookup, Key, F}, _From, #state{tab = T} = State) ->
-    CleanPrio = clean_priority(State#state.life_time),
-    case treap:lookup(Key, T) of
-       {ok, Prio, Val} when (State#state.lru == true) or (Prio =< CleanPrio) ->
-           Hits = State#state.hits,
-           NewState = treap_update(Key, Val, State#state{hits = Hits + 1}),
-           case Val of
-               '$cached_mismatch' ->
-                   {reply, error, NewState};
-               _ ->
-                   {reply, {ok, Val}, NewState}
-           end;
-       _ ->
-           case catch F() of
-               {ok, Val} ->
-                   Miss = State#state.miss,
-                   NewState = treap_insert(Key, Val, State),
-                   {reply, {ok, Val}, NewState#state{miss = Miss + 1}};
-               {'EXIT', Reason} ->
-                   print_error(lookup, [Key], Reason, State),
-                   {reply, error, State};
-               _ ->
-                   Miss = State#state.miss,
-                   NewState = State#state{miss = Miss + 1},
-                   if State#state.cache_missed ->
-                           {reply, error,
-                            treap_insert(Key, '$cached_mismatch', NewState)};
-                      true ->
-                           {reply, error, NewState}
-                   end
-           end
-    end;
-handle_call({cache_lookup, Key}, _From, #state{tab = T} = State) ->
-    CleanPrio = clean_priority(State#state.life_time),
-    case treap:lookup(Key, T) of
-       {ok, Prio, Val} when (State#state.lru == true) or (Prio =< CleanPrio) ->
-           Hits = State#state.hits,
-           NewState = treap_update(Key, Val, State#state{hits = Hits + 1}),
-           {reply, {ok, Val}, NewState};
-       _ ->
-           Miss = State#state.miss,
-           NewState = State#state{miss = Miss + 1},
-           {reply, error, NewState}
-    end;
-handle_call({insert, Key, Val, F}, _From, #state{tab = T} = State) ->
-    case treap:lookup(Key, T) of
-       {ok, _Prio, Val} ->
-           {reply, ok, treap_update(Key, Val, State)};
-       _ ->
-           case catch F() of
-               {'EXIT', Reason} ->
-                   print_error(insert, [Key, Val], Reason, State),
-                   {reply, ok, State};
-               _ ->
-                   {reply, ok, treap_insert(Key, Val, State)}
-           end
-    end;
-handle_call({cache_insert, _, '$cached_mismatch'}, _From,
-           #state{cache_missed = false} = State) ->
-    {reply, ok, State};
-handle_call({cache_insert, Key, Val}, _From, State) ->
-    {reply, ok, treap_insert(Key, Val, State)};
-handle_call({delete, Key, F}, _From, State) ->
-    NewState = treap_delete(Key, State),
-    case catch F() of
-       {'EXIT', Reason} ->
-           print_error(delete, [Key], Reason, State);
-       _ ->
-           ok
-    end,
-    {reply, ok, NewState};
-handle_call({cache_delete, Key}, _From, State) ->
-    NewState = treap_delete(Key, State),
-    {reply, ok, NewState};
-handle_call({info, Info}, _From, State) ->
-    Res = case Info of
-             size ->
-                 State#state.size;
-             ratio ->
-                 {State#state.hits, State#state.miss};
-             all ->
-                 [{max_size, State#state.max_size},
-                  {life_time, State#state.life_time},
-                  {shrink_size, State#state.shrink_size},
-                  {size, State#state.size},
-                  {owner, State#state.owner},
-                  {hits, State#state.hits},
-                  {miss, State#state.miss},
-                  {cache_missed, State#state.cache_missed},
-                  {lru, State#state.lru},
-                  {warn, State#state.warn}];
-             _ ->
-                 badarg
-         end,
-    {reply, Res, State};
-handle_call(tab2list, _From, #state{tab = T} = State) ->
-    Res = treap:fold(
-           fun({Key, _, Val}, Acc) ->
-                   [{Key, Val}|Acc]
-           end, [], T),
-    {reply, Res, State};
-handle_call({setopts, Opts}, _From, State) ->
-    {reply, ok, do_setopts(State, Opts)};
-handle_call(_Request, _From, State) ->
-    Reply = ok,
-    {reply, Reply, State}.
-
-handle_cast(_Msg, State) ->
-    {noreply, State}.
-
-handle_info(_Info, State) ->
-    {noreply, State}.
-
-terminate(_Reason, _State) ->
-    ok.
-
-code_change(_OldVsn, State, _Extra) ->
-    {ok, State}.
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
-do_setopts(#state{procs_num = N} = State, Opts) ->
-    MaxSize = case {proplists:get_value(max_size, Opts),
-                   State#state.max_size} of
-                 {MS, _} when is_integer(MS), MS > 0 ->
-                     round(MS/N);
-                 {unlimited, _} ->
-                     unlimited;
-                 {_, undefined} ->
-                     round(?MAX_SIZE/N);
-                 {_, MS} ->
-                     MS
-             end,
-    LifeTime = case {proplists:get_value(life_time, Opts),
-                    State#state.life_time} of
-                  {LT, _} when is_integer(LT), LT > 0 ->
-                      LT*1000*1000;
-                  {unlimited, _} ->
-                      unlimited;
-                  {_, undefined} ->
-                      ?LIFETIME*1000*1000;
-                  {_, LT} ->
-                      LT
-              end,
-    ShrinkSize = case {proplists:get_value(shrink_size, Opts),
-                      State#state.shrink_size} of
-                    {SS, _} when is_integer(SS), SS > 0 ->
-                        round(SS/N);
-                    _ when is_integer(MaxSize) ->
-                        round(MaxSize/2);
-                    _ ->
-                        unlimited
-                end,
-    Warn = case {proplists:get_value(warn, Opts),
-                State#state.warn} of
-              {true, _} ->
-                  true;
-              {false, _} ->
-                  false;
-              {_, undefined} ->
-                  ?WARN;
-              {_, W} ->
-                  W
-          end,
-    CacheMissed = case proplists:get_value(
-                        cache_missed, Opts, State#state.cache_missed) of
-                     false ->
-                         false;
-                     true ->
-                         true;
-                     _ ->
-                         ?CACHE_MISSED
-                 end,
-    LRU = case proplists:get_value(
-                lru, Opts, State#state.lru) of
-             false ->
-                 false;
-             true ->
-                 true;
-             _ ->
-                 ?LRU
-         end,
-    State#state{max_size = MaxSize,
-               warn = Warn,
-               life_time = LifeTime,
-               cache_missed = CacheMissed,
-               lru = LRU,
-               shrink_size = ShrinkSize}.
-
-get_proc_num() ->
-    case catch erlang:system_info(logical_processors) of
-        Num when is_integer(Num) ->
-            Num;
-        _ ->
-            1
-    end.
-
-get_proc_by_hash(Tab, Term) ->
-    N = erlang:phash2(Term, get_proc_num()) + 1,
-    get_proc(Tab, N).
-
-get_proc(Tab, N) ->
-    list_to_atom(atom_to_list(?PROCNAME) ++ "_" ++
-                atom_to_list(Tab) ++ "_" ++ integer_to_list(N)).
-
-get_all_procs(Tab) ->
-    [get_proc(Tab, N) || N <- lists:seq(1, get_proc_num())].
-
-now_priority() ->
-    {MSec, Sec, USec} = now(),
-    -((MSec*1000000 + Sec)*1000000 + USec).
-
-clean_priority(LifeTime) ->
-    if is_integer(LifeTime) ->
-           now_priority() + LifeTime;
-       true ->
-           unlimited
-    end.
-
-treap_update(Key, Val, #state{tab = T, lru = LRU} = State) ->
-    if LRU ->
-           Priority = now_priority(),
-           NewT = treap:insert(Key, Priority, Val, T),
-           State#state{tab = NewT};
-       true ->
-           State
-    end.
-
-treap_insert(Key, Val, State) ->
-    State1 = clean_treap(State),
-    #state{size = Size} = State2 = shrink_treap(State1),
-    T = State2#state.tab,
-    case treap:lookup(Key, T) of
-       {ok, _, Val} ->
-           treap_update(Key, Val, State2);
-       {ok, _, _} ->
-           NewT = treap:insert(Key, now_priority(), Val, T),
-           State2#state{tab = NewT};
-       _ ->
-           NewT = treap:insert(Key, now_priority(), Val, T),
-           State2#state{tab = NewT, size = Size+1}
-    end.
-
-treap_delete(Key, #state{tab = T, size = Size} = State) ->
-    case treap:lookup(Key, T) of
-       {ok, _, _} ->
-           NewT = treap:delete(Key, T),            
-           clean_treap(State#state{tab = NewT, size = Size-1});
-       _ ->
-           State
-    end.
-
-clean_treap(#state{tab = T, size = Size, life_time = LifeTime} = State) ->
-    if is_integer(LifeTime) ->
-           Priority = now_priority(),
-           {Cleaned, NewT} = clean_treap(T, Priority + LifeTime, 0),
-           State#state{size = Size - Cleaned, tab = NewT};
-       true ->
-           State
-    end.
-
-clean_treap(Treap, CleanPriority, N) ->
-    case treap:is_empty(Treap) of
-        true ->
-            {N, Treap};
-        false ->
-            {_Key, Priority, _Value} = treap:get_root(Treap),
-            if Priority > CleanPriority ->
-                    clean_treap(treap:delete_root(Treap), CleanPriority, N+1);
-              true ->
-                    {N, Treap}
-            end
-    end.
-
-shrink_treap(#state{tab = T,
-                   max_size = MaxSize,
-                   shrink_size = ShrinkSize,
-                   warn = Warn,
-                   size = Size} = State) when Size >= MaxSize ->
-    if Warn ->
-           ?WARNING_MSG("shrinking table:~n"
-                        "** Table: ~p~n"
-                        "** Processes Number: ~p~n"
-                        "** Max Size: ~p items~n"
-                        "** Shrink Size: ~p items~n"
-                        "** Life Time: ~p microseconds~n"
-                        "** Hits/Miss: ~p/~p~n"
-                        "** Owner: ~p~n"
-                        "** Cache Missed: ~p~n"
-                        "** Instruction: you have to tune cacheing options"
-                        " if this message repeats too frequently",
-                        [State#state.name, State#state.procs_num,
-                         MaxSize, ShrinkSize, State#state.life_time,
-                         State#state.hits, State#state.miss,
-                         State#state.owner, State#state.cache_missed]);
-       true ->
-           ok
-    end,
-    {Shrinked, NewT} = shrink_treap(T, ShrinkSize, 0),
-    State#state{tab = NewT, size = Size - Shrinked};
-shrink_treap(State) ->
-    State.
-
-shrink_treap(T, ShrinkSize, ShrinkSize) ->
-    {ShrinkSize, T};
-shrink_treap(T, ShrinkSize, N) ->
-    case treap:is_empty(T) of
-       true ->
-           {N, T};
-       false ->
-           shrink_treap(treap:delete_root(T), ShrinkSize, N+1)
-    end.
-
-print_error(Operation, Args, Reason, State) ->
-    ?ERROR_MSG("callback failed:~n"
-              "** Tab: ~p~n"
-              "** Owner: ~p~n"
-              "** Operation: ~p~n"
-              "** Args: ~p~n"
-              "** Reason: ~p",
-              [State#state.name, State#state.owner,
-               Operation, Args, Reason]).
-
-%%--------------------------------------------------------------------
-%%% Tests
-%%--------------------------------------------------------------------
--define(lookup, dirty_lookup).
--define(delete, dirty_delete).
--define(insert, dirty_insert).
-%%-define(lookup, lookup).
-%%-define(delete, delete).
-%%-define(insert, insert).
-
-test() ->
-    LifeTime = 2,
-    ok = new(test_tbl, [{life_time, LifeTime}, {max_size, unlimited}]),
-    check([]),
-    ok = ?insert(test_tbl, "key", "value", fun() -> ok end),
-    check([{"key", "value"}]),
-    {ok, "value"} = ?lookup(test_tbl, "key", fun() -> error end),
-    check([{"key", "value"}]),
-    io:format("** waiting for ~p seconds to check if LRU works fine...~n",
-             [LifeTime+1]),
-    timer:sleep(timer:seconds(LifeTime+1)),
-    ok = ?insert(test_tbl, "key1", "value1", fun() -> ok end),
-    check([{"key1", "value1"}]),
-    ok = ?delete(test_tbl, "key1", fun() -> ok end),
-    {ok, "value"} = ?lookup(test_tbl, "key", fun() -> {ok, "value"} end),
-    check([{"key", "value"}]),
-    ok = ?delete(test_tbl, "key", fun() -> ok end),
-    check([]),
-    %% io:format("** testing buggy callbacks...~n"),
-    %% delete(test_tbl, "key", fun() -> erlang:error(badarg) end),
-    %% insert(test_tbl, "key", "val", fun() -> erlang:error(badarg) end),
-    %% lookup(test_tbl, "key", fun() -> erlang:error(badarg) end),
-    check([]),
-    delete(test_tbl),
-    test1().
-
-test1() ->
-    MaxSize = 10,
-    ok = new(test_tbl, [{max_size, MaxSize}, {shrink_size, 1}, {warn, false}]),
-    lists:foreach(
-      fun(N) ->
-             ok = ?insert(test_tbl, N, N, fun() -> ok end)
-      end, lists:seq(1, MaxSize*get_proc_num())),
-    {ok, MaxSize} = info(test_tbl, size),
-    delete(test_tbl),
-    test2().
-
-test2() ->
-    LifeTime = 2,
-    ok = new(test_tbl, [{life_time, LifeTime},
-                       {max_size, unlimited},
-                       {lru, false}]),
-    check([]),
-    ok = ?insert(test_tbl, "key", "value", fun() -> ok end),
-    {ok, "value"} = ?lookup(test_tbl, "key", fun() -> error end),
-    check([{"key", "value"}]),
-    io:format("** waiting for ~p seconds to check if non-LRU works fine...~n",
-             [LifeTime+1]),
-    timer:sleep(timer:seconds(LifeTime+1)),
-    error = ?lookup(test_tbl, "key", fun() -> error end),
-    check([{"key", '$cached_mismatch'}]),
-    ok = ?insert(test_tbl, "key", "value1", fun() -> ok end),
-    check([{"key", "value1"}]),
-    delete(test_tbl),
-    io:format("** testing speed, this may take a while...~n"),
-    test3(1000),
-    test3(10000),
-    test3(100000),
-    test3(1000000).
-
-test3(Iter) ->
-    ok = new(test_tbl, [{max_size, unlimited}, {life_time, unlimited}]),
-    L = lists:seq(1, Iter),
-    T1 = now(),
-    lists:foreach(
-      fun(N) ->
-             ok = ?insert(test_tbl, N, N, fun() -> ok end)
-      end, L),
-    io:format("** average insert (size = ~p): ~p usec~n",
-             [Iter, round(timer:now_diff(now(), T1)/Iter)]),
-    T2 = now(),
-    lists:foreach(
-      fun(N) ->
-             {ok, N} = ?lookup(test_tbl, N, fun() -> ok end)
-      end, L),
-    io:format("** average lookup (size = ~p): ~p usec~n",
-             [Iter, round(timer:now_diff(now(), T2)/Iter)]),
-    {ok, Iter} = info(test_tbl, size),
-    delete(test_tbl).
-
-check(List) ->
-    Size = length(List),
-    {ok, Size} = info(test_tbl, size),
-    List = tab2list(test_tbl).
diff --git a/src/cache_tab_sup.erl b/src/cache_tab_sup.erl
deleted file mode 100644 (file)
index 5b016f6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : cache_tab_sup.erl
-%%% Author  : Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%% Description : Cache tables supervisor
-%%%
-%%% Created : 30 Aug 2010 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%-------------------------------------------------------------------
--module(cache_tab_sup).
-
--behaviour(supervisor).
-
-%% API
--export([start_link/0]).
-
-%% Supervisor callbacks
--export([init/1]).
-
--define(SERVER, ?MODULE).
-
-%%====================================================================
-%% API functions
-%%====================================================================
-start_link() ->
-    supervisor:start_link({local, ?SERVER}, ?MODULE, []).
-
-%%====================================================================
-%% Supervisor callbacks
-%%====================================================================
-init([]) ->
-    {ok, {{one_for_one,10,1}, []}}.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
diff --git a/src/config.guess b/src/config.guess
deleted file mode 100644 (file)
index e3a2116..0000000
+++ /dev/null
@@ -1,1533 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-#   Free Software Foundation, Inc.
-
-timestamp='2009-06-10'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub.  If it succeeds, it prints the system name on stdout, and
-# exits with 0.  Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )        # Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help" >&2
-       exit 1 ;;
-    * )
-       break ;;
-  esac
-done
-
-if test $# != 0; then
-  echo "$me: too many arguments$help" >&2
-  exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > $dummy.c ;
-       for c in cc gcc c89 c99 ; do
-         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
-            CC_FOR_BUILD="$c"; break ;
-         fi ;
-       done ;
-       if test x"$CC_FOR_BUILD" = x ; then
-         CC_FOR_BUILD=no_compiler_found ;
-       fi
-       ;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
-       PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
-    *:NetBSD:*:*)
-       # NetBSD (nbsd) targets should (where applicable) match one or
-       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
-       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
-       # switched to ELF, *-*-netbsd* would select the old
-       # object file format.  This provides both forward
-       # compatibility and a consistent mechanism for selecting the
-       # object file format.
-       #
-       # Note: NetBSD doesn't particularly care about the vendor
-       # portion of the name.  We always set it to "unknown".
-       sysctl="sysctl -n hw.machine_arch"
-       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
-           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
-       case "${UNAME_MACHINE_ARCH}" in
-           armeb) machine=armeb-unknown ;;
-           arm*) machine=arm-unknown ;;
-           sh3el) machine=shl-unknown ;;
-           sh3eb) machine=sh-unknown ;;
-           sh5el) machine=sh5le-unknown ;;
-           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
-       esac
-       # The Operating System including object format, if it has switched
-       # to ELF recently, or will in the future.
-       case "${UNAME_MACHINE_ARCH}" in
-           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-               eval $set_cc_for_build
-               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-                       | grep -q __ELF__
-               then
-                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
-                   # Return netbsd for either.  FIX?
-                   os=netbsd
-               else
-                   os=netbsdelf
-               fi
-               ;;
-           *)
-               os=netbsd
-               ;;
-       esac
-       # The OS release
-       # Debian GNU/NetBSD machines have a different userland, and
-       # thus, need a distinct triplet. However, they do not need
-       # kernel version information, so it can be replaced with a
-       # suitable tag, in the style of linux-gnu.
-       case "${UNAME_VERSION}" in
-           Debian*)
-               release='-gnu'
-               ;;
-           *)
-               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
-               ;;
-       esac
-       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
-       # contains redundant information, the shorter form:
-       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-       echo "${machine}-${os}${release}"
-       exit ;;
-    *:OpenBSD:*:*)
-       UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-       echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
-       exit ;;
-    *:ekkoBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
-       exit ;;
-    *:SolidBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
-       exit ;;
-    macppc:MirBSD:*:*)
-       echo powerpc-unknown-mirbsd${UNAME_RELEASE}
-       exit ;;
-    *:MirBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
-       exit ;;
-    alpha:OSF1:*:*)
-       case $UNAME_RELEASE in
-       *4.0)
-               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
-               ;;
-       *5.*)
-               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
-               ;;
-       esac
-       # According to Compaq, /usr/sbin/psrinfo has been available on
-       # OSF/1 and Tru64 systems produced since 1995.  I hope that
-       # covers most systems running today.  This code pipes the CPU
-       # types through head -n 1, so we only detect the type of CPU 0.
-       ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
-       case "$ALPHA_CPU_TYPE" in
-           "EV4 (21064)")
-               UNAME_MACHINE="alpha" ;;
-           "EV4.5 (21064)")
-               UNAME_MACHINE="alpha" ;;
-           "LCA4 (21066/21068)")
-               UNAME_MACHINE="alpha" ;;
-           "EV5 (21164)")
-               UNAME_MACHINE="alphaev5" ;;
-           "EV5.6 (21164A)")
-               UNAME_MACHINE="alphaev56" ;;
-           "EV5.6 (21164PC)")
-               UNAME_MACHINE="alphapca56" ;;
-           "EV5.7 (21164PC)")
-               UNAME_MACHINE="alphapca57" ;;
-           "EV6 (21264)")
-               UNAME_MACHINE="alphaev6" ;;
-           "EV6.7 (21264A)")
-               UNAME_MACHINE="alphaev67" ;;
-           "EV6.8CB (21264C)")
-               UNAME_MACHINE="alphaev68" ;;
-           "EV6.8AL (21264B)")
-               UNAME_MACHINE="alphaev68" ;;
-           "EV6.8CX (21264D)")
-               UNAME_MACHINE="alphaev68" ;;
-           "EV6.9A (21264/EV69A)")
-               UNAME_MACHINE="alphaev69" ;;
-           "EV7 (21364)")
-               UNAME_MACHINE="alphaev7" ;;
-           "EV7.9 (21364A)")
-               UNAME_MACHINE="alphaev79" ;;
-       esac
-       # A Pn.n version is a patched version.
-       # A Vn.n version is a released version.
-       # A Tn.n version is a released field test version.
-       # A Xn.n version is an unreleased experimental baselevel.
-       # 1.2 uses "1.2" for uname -r.
-       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-       exit ;;
-    Alpha\ *:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # Should we change UNAME_MACHINE based on the output of uname instead
-       # of the specific Alpha model?
-       echo alpha-pc-interix
-       exit ;;
-    21064:Windows_NT:50:3)
-       echo alpha-dec-winnt3.5
-       exit ;;
-    Amiga*:UNIX_System_V:4.0:*)
-       echo m68k-unknown-sysv4
-       exit ;;
-    *:[Aa]miga[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-amigaos
-       exit ;;
-    *:[Mm]orph[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-morphos
-       exit ;;
-    *:OS/390:*:*)
-       echo i370-ibm-openedition
-       exit ;;
-    *:z/VM:*:*)
-       echo s390-ibm-zvmoe
-       exit ;;
-    *:OS400:*:*)
-        echo powerpc-ibm-os400
-       exit ;;
-    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-       echo arm-acorn-riscix${UNAME_RELEASE}
-       exit ;;
-    arm:riscos:*:*|arm:RISCOS:*:*)
-       echo arm-unknown-riscos
-       exit ;;
-    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
-       echo hppa1.1-hitachi-hiuxmpp
-       exit ;;
-    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
-       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-       if test "`(/bin/universe) 2>/dev/null`" = att ; then
-               echo pyramid-pyramid-sysv3
-       else
-               echo pyramid-pyramid-bsd
-       fi
-       exit ;;
-    NILE*:*:*:dcosx)
-       echo pyramid-pyramid-svr4
-       exit ;;
-    DRS?6000:unix:4.0:6*)
-       echo sparc-icl-nx6
-       exit ;;
-    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
-       case `/usr/bin/uname -p` in
-           sparc) echo sparc-icl-nx7; exit ;;
-       esac ;;
-    s390x:SunOS:*:*)
-       echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    sun4H:SunOS:5.*:*)
-       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-       eval $set_cc_for_build
-       SUN_ARCH="i386"
-       # If there is a compiler, see if it is configured for 64-bit objects.
-       # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
-       # This test works for both compilers.
-       if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-           if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-               (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-               grep IS_64BIT_ARCH >/dev/null
-           then
-               SUN_ARCH="x86_64"
-           fi
-       fi
-       echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    sun4*:SunOS:6*:*)
-       # According to config.sub, this is the proper way to canonicalize
-       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
-       # it's likely to be more like Solaris than SunOS4.
-       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    sun4*:SunOS:*:*)
-       case "`/usr/bin/arch -k`" in
-           Series*|S4*)
-               UNAME_RELEASE=`uname -v`
-               ;;
-       esac
-       # Japanese Language versions have a version number like `4.1.3-JL'.
-       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
-       exit ;;
-    sun3*:SunOS:*:*)
-       echo m68k-sun-sunos${UNAME_RELEASE}
-       exit ;;
-    sun*:*:4.2BSD:*)
-       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
-       case "`/bin/arch`" in
-           sun3)
-               echo m68k-sun-sunos${UNAME_RELEASE}
-               ;;
-           sun4)
-               echo sparc-sun-sunos${UNAME_RELEASE}
-               ;;
-       esac
-       exit ;;
-    aushp:SunOS:*:*)
-       echo sparc-auspex-sunos${UNAME_RELEASE}
-       exit ;;
-    # The situation for MiNT is a little confusing.  The machine name
-    # can be virtually everything (everything which is not
-    # "atarist" or "atariste" at least should have a processor
-    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
-    # to the lowercase version "mint" (or "freemint").  Finally
-    # the system name "TOS" denotes a system which is actually not
-    # MiNT.  But MiNT is downward compatible to TOS, so this should
-    # be no problem.
-    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-       exit ;;
-    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
-        exit ;;
-    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-       exit ;;
-    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit ;;
-    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit ;;
-    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit ;;
-    m68k:machten:*:*)
-       echo m68k-apple-machten${UNAME_RELEASE}
-       exit ;;
-    powerpc:machten:*:*)
-       echo powerpc-apple-machten${UNAME_RELEASE}
-       exit ;;
-    RISC*:Mach:*:*)
-       echo mips-dec-mach_bsd4.3
-       exit ;;
-    RISC*:ULTRIX:*:*)
-       echo mips-dec-ultrix${UNAME_RELEASE}
-       exit ;;
-    VAX*:ULTRIX*:*:*)
-       echo vax-dec-ultrix${UNAME_RELEASE}
-       exit ;;
-    2020:CLIX:*:* | 2430:CLIX:*:*)
-       echo clipper-intergraph-clix${UNAME_RELEASE}
-       exit ;;
-    mips:*:*:UMIPS | mips:*:*:RISCos)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-       int main (int argc, char *argv[]) {
-#else
-       int main (argc, argv) int argc; char *argv[]; {
-#endif
-       #if defined (host_mips) && defined (MIPSEB)
-       #if defined (SYSTYPE_SYSV)
-         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
-       #endif
-       #if defined (SYSTYPE_SVR4)
-         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
-       #endif
-       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
-         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
-       #endif
-       #endif
-         exit (-1);
-       }
-EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c &&
-         dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-         SYSTEM_NAME=`$dummy $dummyarg` &&
-           { echo "$SYSTEM_NAME"; exit; }
-       echo mips-mips-riscos${UNAME_RELEASE}
-       exit ;;
-    Motorola:PowerMAX_OS:*:*)
-       echo powerpc-motorola-powermax
-       exit ;;
-    Motorola:*:4.3:PL8-*)
-       echo powerpc-harris-powermax
-       exit ;;
-    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
-       echo powerpc-harris-powermax
-       exit ;;
-    Night_Hawk:Power_UNIX:*:*)
-       echo powerpc-harris-powerunix
-       exit ;;
-    m88k:CX/UX:7*:*)
-       echo m88k-harris-cxux7
-       exit ;;
-    m88k:*:4*:R4*)
-       echo m88k-motorola-sysv4
-       exit ;;
-    m88k:*:3*:R3*)
-       echo m88k-motorola-sysv3
-       exit ;;
-    AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
-       then
-           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
-              [ ${TARGET_BINARY_INTERFACE}x = x ]
-           then
-               echo m88k-dg-dgux${UNAME_RELEASE}
-           else
-               echo m88k-dg-dguxbcs${UNAME_RELEASE}
-           fi
-       else
-           echo i586-dg-dgux${UNAME_RELEASE}
-       fi
-       exit ;;
-    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
-       echo m88k-dolphin-sysv3
-       exit ;;
-    M88*:*:R3*:*)
-       # Delta 88k system running SVR3
-       echo m88k-motorola-sysv3
-       exit ;;
-    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
-       echo m88k-tektronix-sysv3
-       exit ;;
-    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
-       echo m68k-tektronix-bsd
-       exit ;;
-    *:IRIX*:*:*)
-       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
-       exit ;;
-    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-       echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-       exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
-    i*86:AIX:*:*)
-       echo i386-ibm-aix
-       exit ;;
-    ia64:AIX:*:*)
-       if [ -x /usr/bin/oslevel ] ; then
-               IBM_REV=`/usr/bin/oslevel`
-       else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
-       fi
-       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
-       exit ;;
-    *:AIX:2:3)
-       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-               eval $set_cc_for_build
-               sed 's/^                //' << EOF >$dummy.c
-               #include <sys/systemcfg.h>
-
-               main()
-                       {
-                       if (!__power_pc())
-                               exit(1);
-                       puts("powerpc-ibm-aix3.2.5");
-                       exit(0);
-                       }
-EOF
-               if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
-               then
-                       echo "$SYSTEM_NAME"
-               else
-                       echo rs6000-ibm-aix3.2.5
-               fi
-       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
-               echo rs6000-ibm-aix3.2.4
-       else
-               echo rs6000-ibm-aix3.2
-       fi
-       exit ;;
-    *:AIX:*:[456])
-       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
-       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
-               IBM_ARCH=rs6000
-       else
-               IBM_ARCH=powerpc
-       fi
-       if [ -x /usr/bin/oslevel ] ; then
-               IBM_REV=`/usr/bin/oslevel`
-       else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
-       fi
-       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
-       exit ;;
-    *:AIX:*:*)
-       echo rs6000-ibm-aix
-       exit ;;
-    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
-       echo romp-ibm-bsd4.4
-       exit ;;
-    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
-       exit ;;                             # report: romp-ibm BSD 4.3
-    *:BOSX:*:*)
-       echo rs6000-bull-bosx
-       exit ;;
-    DPX/2?00:B.O.S.:*:*)
-       echo m68k-bull-sysv3
-       exit ;;
-    9000/[34]??:4.3bsd:1.*:*)
-       echo m68k-hp-bsd
-       exit ;;
-    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
-       echo m68k-hp-bsd4.4
-       exit ;;
-    9000/[34678]??:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       case "${UNAME_MACHINE}" in
-           9000/31? )            HP_ARCH=m68000 ;;
-           9000/[34]?? )         HP_ARCH=m68k ;;
-           9000/[678][0-9][0-9])
-               if [ -x /usr/bin/getconf ]; then
-                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                    case "${sc_cpu_version}" in
-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
-                      532)                      # CPU_PA_RISC2_0
-                        case "${sc_kernel_bits}" in
-                          32) HP_ARCH="hppa2.0n" ;;
-                          64) HP_ARCH="hppa2.0w" ;;
-                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
-                        esac ;;
-                    esac
-               fi
-               if [ "${HP_ARCH}" = "" ]; then
-                   eval $set_cc_for_build
-                   sed 's/^              //' << EOF >$dummy.c
-
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
-
-              int main ()
-              {
-              #if defined(_SC_KERNEL_BITS)
-                  long bits = sysconf(_SC_KERNEL_BITS);
-              #endif
-                  long cpu  = sysconf (_SC_CPU_VERSION);
-
-                  switch (cpu)
-               {
-               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-               case CPU_PA_RISC2_0:
-              #if defined(_SC_KERNEL_BITS)
-                   switch (bits)
-                       {
-                       case 64: puts ("hppa2.0w"); break;
-                       case 32: puts ("hppa2.0n"); break;
-                       default: puts ("hppa2.0"); break;
-                       } break;
-              #else  /* !defined(_SC_KERNEL_BITS) */
-                   puts ("hppa2.0"); break;
-              #endif
-               default: puts ("hppa1.0"); break;
-               }
-                  exit (0);
-              }
-EOF
-                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
-                   test -z "$HP_ARCH" && HP_ARCH=hppa
-               fi ;;
-       esac
-       if [ ${HP_ARCH} = "hppa2.0w" ]
-       then
-           eval $set_cc_for_build
-
-           # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
-           # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
-           # generating 64-bit code.  GNU and HP use different nomenclature:
-           #
-           # $ CC_FOR_BUILD=cc ./config.guess
-           # => hppa2.0w-hp-hpux11.23
-           # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
-           # => hppa64-hp-hpux11.23
-
-           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
-               grep -q __LP64__
-           then
-               HP_ARCH="hppa2.0w"
-           else
-               HP_ARCH="hppa64"
-           fi
-       fi
-       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
-       exit ;;
-    ia64:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       echo ia64-hp-hpux${HPUX_REV}
-       exit ;;
-    3050*:HI-UX:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #include <unistd.h>
-       int
-       main ()
-       {
-         long cpu = sysconf (_SC_CPU_VERSION);
-         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
-            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
-            results, however.  */
-         if (CPU_IS_PA_RISC (cpu))
-           {
-             switch (cpu)
-               {
-                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
-                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
-                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
-                 default: puts ("hppa-hitachi-hiuxwe2"); break;
-               }
-           }
-         else if (CPU_IS_HP_MC68K (cpu))
-           puts ("m68k-hitachi-hiuxwe2");
-         else puts ("unknown-hitachi-hiuxwe2");
-         exit (0);
-       }
-EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
-               { echo "$SYSTEM_NAME"; exit; }
-       echo unknown-hitachi-hiuxwe2
-       exit ;;
-    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
-       echo hppa1.1-hp-bsd
-       exit ;;
-    9000/8??:4.3bsd:*:*)
-       echo hppa1.0-hp-bsd
-       exit ;;
-    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
-       echo hppa1.0-hp-mpeix
-       exit ;;
-    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
-       echo hppa1.1-hp-osf
-       exit ;;
-    hp8??:OSF1:*:*)
-       echo hppa1.0-hp-osf
-       exit ;;
-    i*86:OSF1:*:*)
-       if [ -x /usr/sbin/sysversion ] ; then
-           echo ${UNAME_MACHINE}-unknown-osf1mk
-       else
-           echo ${UNAME_MACHINE}-unknown-osf1
-       fi
-       exit ;;
-    parisc*:Lites*:*:*)
-       echo hppa1.1-hp-lites
-       exit ;;
-    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
-       echo c1-convex-bsd
-        exit ;;
-    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
-       if getsysinfo -f scalar_acc
-       then echo c32-convex-bsd
-       else echo c2-convex-bsd
-       fi
-        exit ;;
-    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
-       echo c34-convex-bsd
-        exit ;;
-    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
-       echo c38-convex-bsd
-        exit ;;
-    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
-       echo c4-convex-bsd
-        exit ;;
-    CRAY*Y-MP:*:*:*)
-       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*[A-Z]90:*:*:*)
-       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
-       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-             -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*TS:*:*:*)
-       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*T3E:*:*:*)
-       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    CRAY*SV1:*:*:*)
-       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    *:UNICOS/mp:*:*)
-       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-       exit ;;
-    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit ;;
-    5000:UNIX_System_V:4.*:*)
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-       exit ;;
-    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
-       exit ;;
-    sparc*:BSD/OS:*:*)
-       echo sparc-unknown-bsdi${UNAME_RELEASE}
-       exit ;;
-    *:BSD/OS:*:*)
-       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
-       exit ;;
-    *:FreeBSD:*:*)
-       case ${UNAME_MACHINE} in
-           pc98)
-               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-           amd64)
-               echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-           *)
-               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-       esac
-       exit ;;
-    i*:CYGWIN*:*)
-       echo ${UNAME_MACHINE}-pc-cygwin
-       exit ;;
-    *:MINGW*:*)
-       echo ${UNAME_MACHINE}-pc-mingw32
-       exit ;;
-    i*:windows32*:*)
-       # uname -m includes "-pc" on this system.
-       echo ${UNAME_MACHINE}-mingw32
-       exit ;;
-    i*:PW*:*)
-       echo ${UNAME_MACHINE}-pc-pw32
-       exit ;;
-    *:Interix*:[3456]*)
-       case ${UNAME_MACHINE} in
-           x86)
-               echo i586-pc-interix${UNAME_RELEASE}
-               exit ;;
-           EM64T | authenticamd | genuineintel)
-               echo x86_64-unknown-interix${UNAME_RELEASE}
-               exit ;;
-           IA64)
-               echo ia64-unknown-interix${UNAME_RELEASE}
-               exit ;;
-       esac ;;
-    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
-       echo i${UNAME_MACHINE}-pc-mks
-       exit ;;
-    8664:Windows_NT:*)
-       echo x86_64-pc-mks
-       exit ;;
-    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
-       # UNAME_MACHINE based on the output of uname instead of i386?
-       echo i586-pc-interix
-       exit ;;
-    i*:UWIN*:*)
-       echo ${UNAME_MACHINE}-pc-uwin
-       exit ;;
-    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-       echo x86_64-unknown-cygwin
-       exit ;;
-    p*:CYGWIN*:*)
-       echo powerpcle-unknown-cygwin
-       exit ;;
-    prep*:SunOS:5.*:*)
-       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-       exit ;;
-    *:GNU:*:*)
-       # the GNU system
-       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
-       exit ;;
-    *:GNU/*:*:*)
-       # other systems with GNU libc and userland
-       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
-       exit ;;
-    i*86:Minix:*:*)
-       echo ${UNAME_MACHINE}-pc-minix
-       exit ;;
-    arm*:Linux:*:*)
-       eval $set_cc_for_build
-       if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
-           | grep -q __ARM_EABI__
-       then
-           echo ${UNAME_MACHINE}-unknown-linux-gnu
-       else
-           echo ${UNAME_MACHINE}-unknown-linux-gnueabi
-       fi
-       exit ;;
-    avr32*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    cris:Linux:*:*)
-       echo cris-axis-linux-gnu
-       exit ;;
-    crisv32:Linux:*:*)
-       echo crisv32-axis-linux-gnu
-       exit ;;
-    frv:Linux:*:*)
-       echo frv-unknown-linux-gnu
-       exit ;;
-    ia64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    m32r*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    m68*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    mips:Linux:*:* | mips64:Linux:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #undef CPU
-       #undef ${UNAME_MACHINE}
-       #undef ${UNAME_MACHINE}el
-       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-       CPU=${UNAME_MACHINE}el
-       #else
-       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-       CPU=${UNAME_MACHINE}
-       #else
-       CPU=
-       #endif
-       #endif
-EOF
-       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-           /^CPU/{
-               s: ::g
-               p
-           }'`"
-       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
-       ;;
-    or32:Linux:*:*)
-       echo or32-unknown-linux-gnu
-       exit ;;
-    ppc:Linux:*:*)
-       echo powerpc-unknown-linux-gnu
-       exit ;;
-    ppc64:Linux:*:*)
-       echo powerpc64-unknown-linux-gnu
-       exit ;;
-    alpha:Linux:*:*)
-       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
-         EV5)   UNAME_MACHINE=alphaev5 ;;
-         EV56)  UNAME_MACHINE=alphaev56 ;;
-         PCA56) UNAME_MACHINE=alphapca56 ;;
-         PCA57) UNAME_MACHINE=alphapca56 ;;
-         EV6)   UNAME_MACHINE=alphaev6 ;;
-         EV67)  UNAME_MACHINE=alphaev67 ;;
-         EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
-       objdump --private-headers /bin/sh | grep -q ld.so.1
-       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
-       exit ;;
-    padre:Linux:*:*)
-       echo sparc-unknown-linux-gnu
-       exit ;;
-    parisc:Linux:*:* | hppa:Linux:*:*)
-       # Look for CPU level
-       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-         PA7*) echo hppa1.1-unknown-linux-gnu ;;
-         PA8*) echo hppa2.0-unknown-linux-gnu ;;
-         *)    echo hppa-unknown-linux-gnu ;;
-       esac
-       exit ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-       echo hppa64-unknown-linux-gnu
-       exit ;;
-    s390:Linux:*:* | s390x:Linux:*:*)
-       echo ${UNAME_MACHINE}-ibm-linux
-       exit ;;
-    sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    sh*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    sparc:Linux:*:* | sparc64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    vax:Linux:*:*)
-       echo ${UNAME_MACHINE}-dec-linux-gnu
-       exit ;;
-    x86_64:Linux:*:*)
-       echo x86_64-unknown-linux-gnu
-       exit ;;
-    xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
-       exit ;;
-    i*86:Linux:*:*)
-       # The BFD linker knows what the default object file format is, so
-       # first see if it will tell us. cd to the root directory to prevent
-       # problems with other programs or directories called `ld' in the path.
-       # Set LC_ALL=C to ensure ld outputs messages in English.
-       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
-                        | sed -ne '/supported targets:/!d
-                                   s/[         ][      ]*/ /g
-                                   s/.*supported targets: *//
-                                   s/ .*//
-                                   p'`
-        case "$ld_supported_targets" in
-         elf32-i386)
-               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
-               ;;
-       esac
-       # Determine whether the default compiler is a.out or elf
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #include <features.h>
-       #ifdef __ELF__
-       # ifdef __GLIBC__
-       #  if __GLIBC__ >= 2
-       LIBC=gnu
-       #  else
-       LIBC=gnulibc1
-       #  endif
-       # else
-       LIBC=gnulibc1
-       # endif
-       #else
-       #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-       LIBC=gnu
-       #else
-       LIBC=gnuaout
-       #endif
-       #endif
-       #ifdef __dietlibc__
-       LIBC=dietlibc
-       #endif
-EOF
-       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
-           /^LIBC/{
-               s: ::g
-               p
-           }'`"
-       test x"${LIBC}" != x && {
-               echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
-               exit
-       }
-       test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
-       ;;
-    i*86:DYNIX/ptx:4*:*)
-       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
-       # earlier versions are messed up and put the nodename in both
-       # sysname and nodename.
-       echo i386-sequent-sysv4
-       exit ;;
-    i*86:UNIX_SV:4.2MP:2.*)
-        # Unixware is an offshoot of SVR4, but it has its own version
-        # number series starting with 2...
-        # I am not positive that other SVR4 systems won't match this,
-       # I just have to hope.  -- rms.
-        # Use sysv4.2uw... so that sysv4* matches it.
-       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
-       exit ;;
-    i*86:OS/2:*:*)
-       # If we were able to find `uname', then EMX Unix compatibility
-       # is probably installed.
-       echo ${UNAME_MACHINE}-pc-os2-emx
-       exit ;;
-    i*86:XTS-300:*:STOP)
-       echo ${UNAME_MACHINE}-unknown-stop
-       exit ;;
-    i*86:atheos:*:*)
-       echo ${UNAME_MACHINE}-unknown-atheos
-       exit ;;
-    i*86:syllable:*:*)
-       echo ${UNAME_MACHINE}-pc-syllable
-       exit ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-       echo i386-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    i*86:*DOS:*:*)
-       echo ${UNAME_MACHINE}-pc-msdosdjgpp
-       exit ;;
-    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
-       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
-       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
-       else
-               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
-       fi
-       exit ;;
-    i*86:*:5:[678]*)
-       # UnixWare 7.x, OpenUNIX and OpenServer 6.
-       case `/bin/uname -X | grep "^Machine"` in
-           *486*)           UNAME_MACHINE=i486 ;;
-           *Pentium)        UNAME_MACHINE=i586 ;;
-           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
-       esac
-       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
-       exit ;;
-    i*86:*:3.2:*)
-       if test -f /usr/options/cb.name; then
-               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
-       elif /bin/uname -X 2>/dev/null >/dev/null ; then
-               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
-               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
-               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
-                       && UNAME_MACHINE=i586
-               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
-                       && UNAME_MACHINE=i686
-               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
-                       && UNAME_MACHINE=i686
-               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
-       else
-               echo ${UNAME_MACHINE}-pc-sysv32
-       fi
-       exit ;;
-    pc:*:*:*)
-       # Left here for compatibility:
-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i586.
-       # Note: whatever this is, it MUST be the same as what config.sub
-       # prints for the "djgpp" host, or else GDB configury will decide that
-       # this is a cross-build.
-       echo i586-pc-msdosdjgpp
-        exit ;;
-    Intel:Mach:3*:*)
-       echo i386-pc-mach3
-       exit ;;
-    paragon:*:*:*)
-       echo i860-intel-osf1
-       exit ;;
-    i860:*:4.*:*) # i860-SVR4
-       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
-       else # Add other i860-SVR4 vendors below as they are discovered.
-         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
-       fi
-       exit ;;
-    mini*:CTIX:SYS*5:*)
-       # "miniframe"
-       echo m68010-convergent-sysv
-       exit ;;
-    mc68k:UNIX:SYSTEM5:3.51m)
-       echo m68k-convergent-sysv
-       exit ;;
-    M680?0:D-NIX:5.3:*)
-       echo m68k-diab-dnix
-       exit ;;
-    M68*:*:R3V[5678]*:*)
-       test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
-    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
-       OS_REL=''
-       test -r /etc/.relid \
-       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
-       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-         && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
-       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-         && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
-    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && { echo i486-ncr-sysv4; exit; } ;;
-    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
-       OS_REL='.3'
-       test -r /etc/.relid \
-           && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
-       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-           && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
-       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
-       /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
-    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-       echo m68k-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    mc68030:UNIX_System_V:4.*:*)
-       echo m68k-atari-sysv4
-       exit ;;
-    TSUNAMI:LynxOS:2.*:*)
-       echo sparc-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    rs6000:LynxOS:2.*:*)
-       echo rs6000-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-       echo powerpc-unknown-lynxos${UNAME_RELEASE}
-       exit ;;
-    SM[BE]S:UNIX_SV:*:*)
-       echo mips-dde-sysv${UNAME_RELEASE}
-       exit ;;
-    RM*:ReliantUNIX-*:*:*)
-       echo mips-sni-sysv4
-       exit ;;
-    RM*:SINIX-*:*:*)
-       echo mips-sni-sysv4
-       exit ;;
-    *:SINIX-*:*:*)
-       if uname -p 2>/dev/null >/dev/null ; then
-               UNAME_MACHINE=`(uname -p) 2>/dev/null`
-               echo ${UNAME_MACHINE}-sni-sysv4
-       else
-               echo ns32k-sni-sysv
-       fi
-       exit ;;
-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                      # says <Richard.M.Bartel@ccMail.Census.GOV>
-        echo i586-unisys-sysv4
-        exit ;;
-    *:UNIX_System_V:4*:FTX*)
-       # From Gerald Hewes <hewes@openmarket.com>.
-       # How about differentiating between stratus architectures? -djm
-       echo hppa1.1-stratus-sysv4
-       exit ;;
-    *:*:*:FTX*)
-       # From seanf@swdc.stratus.com.
-       echo i860-stratus-sysv4
-       exit ;;
-    i*86:VOS:*:*)
-       # From Paul.Green@stratus.com.
-       echo ${UNAME_MACHINE}-stratus-vos
-       exit ;;
-    *:VOS:*:*)
-       # From Paul.Green@stratus.com.
-       echo hppa1.1-stratus-vos
-       exit ;;
-    mc68*:A/UX:*:*)
-       echo m68k-apple-aux${UNAME_RELEASE}
-       exit ;;
-    news*:NEWS-OS:6*:*)
-       echo mips-sony-newsos6
-       exit ;;
-    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-       if [ -d /usr/nec ]; then
-               echo mips-nec-sysv${UNAME_RELEASE}
-       else
-               echo mips-unknown-sysv${UNAME_RELEASE}
-       fi
-        exit ;;
-    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
-       echo powerpc-be-beos
-       exit ;;
-    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
-       echo powerpc-apple-beos
-       exit ;;
-    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
-       echo i586-pc-beos
-       exit ;;
-    BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
-       echo i586-pc-haiku
-       exit ;;
-    SX-4:SUPER-UX:*:*)
-       echo sx4-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-5:SUPER-UX:*:*)
-       echo sx5-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-6:SUPER-UX:*:*)
-       echo sx6-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-7:SUPER-UX:*:*)
-       echo sx7-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-8:SUPER-UX:*:*)
-       echo sx8-nec-superux${UNAME_RELEASE}
-       exit ;;
-    SX-8R:SUPER-UX:*:*)
-       echo sx8r-nec-superux${UNAME_RELEASE}
-       exit ;;
-    Power*:Rhapsody:*:*)
-       echo powerpc-apple-rhapsody${UNAME_RELEASE}
-       exit ;;
-    *:Rhapsody:*:*)
-       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
-       exit ;;
-    *:Darwin:*:*)
-       UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       case $UNAME_PROCESSOR in
-           unknown) UNAME_PROCESSOR=powerpc ;;
-       esac
-       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
-       exit ;;
-    *:procnto*:*:* | *:QNX:[0123456789]*:*)
-       UNAME_PROCESSOR=`uname -p`
-       if test "$UNAME_PROCESSOR" = "x86"; then
-               UNAME_PROCESSOR=i386
-               UNAME_MACHINE=pc
-       fi
-       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
-       exit ;;
-    *:QNX:*:4*)
-       echo i386-pc-qnx
-       exit ;;
-    NSE-?:NONSTOP_KERNEL:*:*)
-       echo nse-tandem-nsk${UNAME_RELEASE}
-       exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
-       echo nsr-tandem-nsk${UNAME_RELEASE}
-       exit ;;
-    *:NonStop-UX:*:*)
-       echo mips-compaq-nonstopux
-       exit ;;
-    BS2000:POSIX*:*:*)
-       echo bs2000-siemens-sysv
-       exit ;;
-    DS/*:UNIX_System_V:*:*)
-       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
-       exit ;;
-    *:Plan9:*:*)
-       # "uname -m" is not consistent, so use $cputype instead. 386
-       # is converted to i386 for consistency with other x86
-       # operating systems.
-       if test "$cputype" = "386"; then
-           UNAME_MACHINE=i386
-       else
-           UNAME_MACHINE="$cputype"
-       fi
-       echo ${UNAME_MACHINE}-unknown-plan9
-       exit ;;
-    *:TOPS-10:*:*)
-       echo pdp10-unknown-tops10
-       exit ;;
-    *:TENEX:*:*)
-       echo pdp10-unknown-tenex
-       exit ;;
-    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
-       echo pdp10-dec-tops20
-       exit ;;
-    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
-       echo pdp10-xkl-tops20
-       exit ;;
-    *:TOPS-20:*:*)
-       echo pdp10-unknown-tops20
-       exit ;;
-    *:ITS:*:*)
-       echo pdp10-unknown-its
-       exit ;;
-    SEI:*:*:SEIUX)
-        echo mips-sei-seiux${UNAME_RELEASE}
-       exit ;;
-    *:DragonFly:*:*)
-       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-       exit ;;
-    *:*VMS:*:*)
-       UNAME_MACHINE=`(uname -p) 2>/dev/null`
-       case "${UNAME_MACHINE}" in
-           A*) echo alpha-dec-vms ; exit ;;
-           I*) echo ia64-dec-vms ; exit ;;
-           V*) echo vax-dec-vms ; exit ;;
-       esac ;;
-    *:XENIX:*:SysV)
-       echo i386-pc-xenix
-       exit ;;
-    i*86:skyos:*:*)
-       echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
-       exit ;;
-    i*86:rdos:*:*)
-       echo ${UNAME_MACHINE}-pc-rdos
-       exit ;;
-    i*86:AROS:*:*)
-       echo ${UNAME_MACHINE}-pc-aros
-       exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-          "4"
-#else
-         ""
-#endif
-         ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
-  int version;
-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
-  if (version < 4)
-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
-  else
-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-  exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
-  printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
-  printf ("ns32k-encore-mach\n"); exit (0);
-#else
-  printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
-  printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
-  printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
-  printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
-
-    if (strncmp(un.version, "V2", 2) == 0) {
-       printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-       printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-#  include <sys/param.h>
-#  if defined (BSD)
-#   if BSD == 43
-      printf ("vax-dec-bsd4.3\n"); exit (0);
-#   else
-#    if BSD == 199006
-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
-#    else
-      printf ("vax-dec-bsd\n"); exit (0);
-#    endif
-#   endif
-#  else
-    printf ("vax-dec-bsd\n"); exit (0);
-#  endif
-# else
-    printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
-  printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
-  exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
-       { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-       echo c1-convex-bsd
-       exit ;;
-    c2*)
-       if getsysinfo -f scalar_acc
-       then echo c32-convex-bsd
-       else echo c2-convex-bsd
-       fi
-       exit ;;
-    c34*)
-       echo c34-convex-bsd
-       exit ;;
-    c38*)
-       echo c38-convex-bsd
-       exit ;;
-    c4*)
-       echo c4-convex-bsd
-       exit ;;
-    esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo               = `(hostinfo) 2>/dev/null`
-/bin/universe          = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch              = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM  = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/src/config.sub b/src/config.sub
deleted file mode 100644 (file)
index eb0389a..0000000
+++ /dev/null
@@ -1,1693 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-#   Free Software Foundation, Inc.
-
-timestamp='2009-06-11'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine.  It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support.  The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
-  -h, --help         print this help, then exit
-  -t, --time-stamp   print date of last modification, then exit
-  -v, --version      print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
-  case $1 in
-    --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
-    --version | -v )
-       echo "$version" ; exit ;;
-    --help | --h* | -h )
-       echo "$usage"; exit ;;
-    -- )     # Stop option processing
-       shift; break ;;
-    - )        # Use stdin as input.
-       break ;;
-    -* )
-       echo "$me: invalid option $1$help"
-       exit 1 ;;
-
-    *local*)
-       # First pass through any local machine types.
-       echo $1
-       exit ;;
-
-    * )
-       break ;;
-  esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
-    exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
-    exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-       -sun*os*)
-               # Prevent following clause from handling this invalid input.
-               ;;
-       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray)
-               os=
-               basic_machine=$1
-               ;;
-        -bluegene*)
-               os=-cnk
-               ;;
-       -sim | -cisco | -oki | -wec | -winbond)
-               os=
-               basic_machine=$1
-               ;;
-       -scout)
-               ;;
-       -wrs)
-               os=-vxworks
-               basic_machine=$1
-               ;;
-       -chorusos*)
-               os=-chorusos
-               basic_machine=$1
-               ;;
-       -chorusrdb)
-               os=-chorusrdb
-               basic_machine=$1
-               ;;
-       -hiux*)
-               os=-hiuxwe2
-               ;;
-       -sco6)
-               os=-sco5v6
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5)
-               os=-sco3.2v5
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco4)
-               os=-sco3.2v4
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2.[4-9]*)
-               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco3.2v[4-9]*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco5v6*)
-               # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -sco*)
-               os=-sco3.2v2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -udk*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -isc)
-               os=-isc2.2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -clix*)
-               basic_machine=clipper-intergraph
-               ;;
-       -isc*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-               ;;
-       -lynx*)
-               os=-lynxos
-               ;;
-       -ptx*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-               ;;
-       -windowsnt*)
-               os=`echo $os | sed -e 's/windowsnt/winnt/'`
-               ;;
-       -psos*)
-               os=-psos
-               ;;
-       -mint | -mint[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
-       # Recognize the basic CPU types without company name.
-       # Some are omitted here because they have special meanings below.
-       1750a | 580 \
-       | a29k \
-       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-       | am33_2.0 \
-       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
-       | bfin \
-       | c4x | clipper \
-       | d10v | d30v | dlx | dsp16xx \
-       | fido | fr30 | frv \
-       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-       | i370 | i860 | i960 | ia64 \
-       | ip2k | iq2000 \
-       | lm32 \
-       | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | mcore | mep | metag \
-       | mips | mipsbe | mipseb | mipsel | mipsle \
-       | mips16 \
-       | mips64 | mips64el \
-       | mips64octeon | mips64octeonel \
-       | mips64orion | mips64orionel \
-       | mips64r5900 | mips64r5900el \
-       | mips64vr | mips64vrel \
-       | mips64vr4100 | mips64vr4100el \
-       | mips64vr4300 | mips64vr4300el \
-       | mips64vr5000 | mips64vr5000el \
-       | mips64vr5900 | mips64vr5900el \
-       | mipsisa32 | mipsisa32el \
-       | mipsisa32r2 | mipsisa32r2el \
-       | mipsisa64 | mipsisa64el \
-       | mipsisa64r2 | mipsisa64r2el \
-       | mipsisa64sb1 | mipsisa64sb1el \
-       | mipsisa64sr71k | mipsisa64sr71kel \
-       | mipstx39 | mipstx39el \
-       | mn10200 | mn10300 \
-       | moxie \
-       | mt \
-       | msp430 \
-       | nios | nios2 \
-       | ns16k | ns32k \
-       | or32 \
-       | pdp10 | pdp11 | pj | pjl \
-       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
-       | pyramid \
-       | score \
-       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-       | sh64 | sh64le \
-       | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-       | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-       | spu | strongarm \
-       | tahoe | thumb | tic4x | tic80 | tron \
-       | v850 | v850e \
-       | we32k \
-       | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
-       | z8k | z80)
-               basic_machine=$basic_machine-unknown
-               ;;
-       m6811 | m68hc11 | m6812 | m68hc12)
-               # Motorola 68HC11/12.
-               basic_machine=$basic_machine-unknown
-               os=-none
-               ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
-               ;;
-       ms1)
-               basic_machine=mt-unknown
-               ;;
-
-       # We use `pc' rather than `unknown'
-       # because (1) that's what they normally are, and
-       # (2) the word "unknown" tends to confuse beginning users.
-       i*86 | x86_64)
-         basic_machine=$basic_machine-pc
-         ;;
-       # Object if more than one company name word.
-       *-*-*)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-       # Recognize the basic CPU types with company name.
-       580-* \
-       | a29k-* \
-       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
-       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-       | avr-* | avr32-* \
-       | bfin-* | bs2000-* \
-       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
-       | clipper-* | craynv-* | cydra-* \
-       | d10v-* | d30v-* | dlx-* \
-       | elxsi-* \
-       | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-       | h8300-* | h8500-* \
-       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-       | i*86-* | i860-* | i960-* | ia64-* \
-       | ip2k-* | iq2000-* \
-       | lm32-* \
-       | m32c-* | m32r-* | m32rle-* \
-       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-       | mips16-* \
-       | mips64-* | mips64el-* \
-       | mips64octeon-* | mips64octeonel-* \
-       | mips64orion-* | mips64orionel-* \
-       | mips64r5900-* | mips64r5900el-* \
-       | mips64vr-* | mips64vrel-* \
-       | mips64vr4100-* | mips64vr4100el-* \
-       | mips64vr4300-* | mips64vr4300el-* \
-       | mips64vr5000-* | mips64vr5000el-* \
-       | mips64vr5900-* | mips64vr5900el-* \
-       | mipsisa32-* | mipsisa32el-* \
-       | mipsisa32r2-* | mipsisa32r2el-* \
-       | mipsisa64-* | mipsisa64el-* \
-       | mipsisa64r2-* | mipsisa64r2el-* \
-       | mipsisa64sb1-* | mipsisa64sb1el-* \
-       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
-       | mipstx39-* | mipstx39el-* \
-       | mmix-* \
-       | mt-* \
-       | msp430-* \
-       | nios-* | nios2-* \
-       | none-* | np1-* | ns16k-* | ns32k-* \
-       | orion-* \
-       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
-       | pyramid-* \
-       | romp-* | rs6000-* \
-       | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-       | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-       | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
-       | tahoe-* | thumb-* \
-       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
-       | tron-* \
-       | v850-* | v850e-* | vax-* \
-       | we32k-* \
-       | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
-       | xstormy16-* | xtensa*-* \
-       | ymp-* \
-       | z8k-* | z80-*)
-               ;;
-       # Recognize the basic CPU types without company name, with glob match.
-       xtensa*)
-               basic_machine=$basic_machine-unknown
-               ;;
-       # Recognize the various machine names and aliases which stand
-       # for a CPU type and a company and sometimes even an OS.
-       386bsd)
-               basic_machine=i386-unknown
-               os=-bsd
-               ;;
-       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-               basic_machine=m68000-att
-               ;;
-       3b*)
-               basic_machine=we32k-att
-               ;;
-       a29khif)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       abacus)
-               basic_machine=abacus-unknown
-               ;;
-       adobe68k)
-               basic_machine=m68010-adobe
-               os=-scout
-               ;;
-       alliant | fx80)
-               basic_machine=fx80-alliant
-               ;;
-       altos | altos3068)
-               basic_machine=m68k-altos
-               ;;
-       am29k)
-               basic_machine=a29k-none
-               os=-bsd
-               ;;
-       amd64)
-               basic_machine=x86_64-pc
-               ;;
-       amd64-*)
-               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       amdahl)
-               basic_machine=580-amdahl
-               os=-sysv
-               ;;
-       amiga | amiga-*)
-               basic_machine=m68k-unknown
-               ;;
-       amigaos | amigados)
-               basic_machine=m68k-unknown
-               os=-amigaos
-               ;;
-       amigaunix | amix)
-               basic_machine=m68k-unknown
-               os=-sysv4
-               ;;
-       apollo68)
-               basic_machine=m68k-apollo
-               os=-sysv
-               ;;
-       apollo68bsd)
-               basic_machine=m68k-apollo
-               os=-bsd
-               ;;
-       aros)
-               basic_machine=i386-pc
-               os=-aros
-               ;;
-       aux)
-               basic_machine=m68k-apple
-               os=-aux
-               ;;
-       balance)
-               basic_machine=ns32k-sequent
-               os=-dynix
-               ;;
-       blackfin)
-               basic_machine=bfin-unknown
-               os=-linux
-               ;;
-       blackfin-*)
-               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       bluegene*)
-               basic_machine=powerpc-ibm
-               os=-cnk
-               ;;
-       c90)
-               basic_machine=c90-cray
-               os=-unicos
-               ;;
-        cegcc)
-               basic_machine=arm-unknown
-               os=-cegcc
-               ;;
-       convex-c1)
-               basic_machine=c1-convex
-               os=-bsd
-               ;;
-       convex-c2)
-               basic_machine=c2-convex
-               os=-bsd
-               ;;
-       convex-c32)
-               basic_machine=c32-convex
-               os=-bsd
-               ;;
-       convex-c34)
-               basic_machine=c34-convex
-               os=-bsd
-               ;;
-       convex-c38)
-               basic_machine=c38-convex
-               os=-bsd
-               ;;
-       cray | j90)
-               basic_machine=j90-cray
-               os=-unicos
-               ;;
-       craynv)
-               basic_machine=craynv-cray
-               os=-unicosmp
-               ;;
-       cr16)
-               basic_machine=cr16-unknown
-               os=-elf
-               ;;
-       crds | unos)
-               basic_machine=m68k-crds
-               ;;
-       crisv32 | crisv32-* | etraxfs*)
-               basic_machine=crisv32-axis
-               ;;
-       cris | cris-* | etrax*)
-               basic_machine=cris-axis
-               ;;
-       crx)
-               basic_machine=crx-unknown
-               os=-elf
-               ;;
-       da30 | da30-*)
-               basic_machine=m68k-da30
-               ;;
-       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-               basic_machine=mips-dec
-               ;;
-       decsystem10* | dec10*)
-               basic_machine=pdp10-dec
-               os=-tops10
-               ;;
-       decsystem20* | dec20*)
-               basic_machine=pdp10-dec
-               os=-tops20
-               ;;
-       delta | 3300 | motorola-3300 | motorola-delta \
-             | 3300-motorola | delta-motorola)
-               basic_machine=m68k-motorola
-               ;;
-       delta88)
-               basic_machine=m88k-motorola
-               os=-sysv3
-               ;;
-       dicos)
-               basic_machine=i686-pc
-               os=-dicos
-               ;;
-       djgpp)
-               basic_machine=i586-pc
-               os=-msdosdjgpp
-               ;;
-       dpx20 | dpx20-*)
-               basic_machine=rs6000-bull
-               os=-bosx
-               ;;
-       dpx2* | dpx2*-bull)
-               basic_machine=m68k-bull
-               os=-sysv3
-               ;;
-       ebmon29k)
-               basic_machine=a29k-amd
-               os=-ebmon
-               ;;
-       elxsi)
-               basic_machine=elxsi-elxsi
-               os=-bsd
-               ;;
-       encore | umax | mmax)
-               basic_machine=ns32k-encore
-               ;;
-       es1800 | OSE68k | ose68k | ose | OSE)
-               basic_machine=m68k-ericsson
-               os=-ose
-               ;;
-       fx2800)
-               basic_machine=i860-alliant
-               ;;
-       genix)
-               basic_machine=ns32k-ns
-               ;;
-       gmicro)
-               basic_machine=tron-gmicro
-               os=-sysv
-               ;;
-       go32)
-               basic_machine=i386-pc
-               os=-go32
-               ;;
-       h3050r* | hiux*)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       h8300hms)
-               basic_machine=h8300-hitachi
-               os=-hms
-               ;;
-       h8300xray)
-               basic_machine=h8300-hitachi
-               os=-xray
-               ;;
-       h8500hms)
-               basic_machine=h8500-hitachi
-               os=-hms
-               ;;
-       harris)
-               basic_machine=m88k-harris
-               os=-sysv3
-               ;;
-       hp300-*)
-               basic_machine=m68k-hp
-               ;;
-       hp300bsd)
-               basic_machine=m68k-hp
-               os=-bsd
-               ;;
-       hp300hpux)
-               basic_machine=m68k-hp
-               os=-hpux
-               ;;
-       hp3k9[0-9][0-9] | hp9[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k2[0-9][0-9] | hp9k31[0-9])
-               basic_machine=m68000-hp
-               ;;
-       hp9k3[2-9][0-9])
-               basic_machine=m68k-hp
-               ;;
-       hp9k6[0-9][0-9] | hp6[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hp9k7[0-79][0-9] | hp7[0-79][0-9])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k78[0-9] | hp78[0-9])
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-               # FIXME: really hppa2.0-hp
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][13679] | hp8[0-9][13679])
-               basic_machine=hppa1.1-hp
-               ;;
-       hp9k8[0-9][0-9] | hp8[0-9][0-9])
-               basic_machine=hppa1.0-hp
-               ;;
-       hppa-next)
-               os=-nextstep3
-               ;;
-       hppaosf)
-               basic_machine=hppa1.1-hp
-               os=-osf
-               ;;
-       hppro)
-               basic_machine=hppa1.1-hp
-               os=-proelf
-               ;;
-       i370-ibm* | ibm*)
-               basic_machine=i370-ibm
-               ;;
-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
-       i*86v32)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv32
-               ;;
-       i*86v4*)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv4
-               ;;
-       i*86v)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-sysv
-               ;;
-       i*86sol2)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
-               os=-solaris2
-               ;;
-       i386mach)
-               basic_machine=i386-mach
-               os=-mach
-               ;;
-       i386-vsta | vsta)
-               basic_machine=i386-unknown
-               os=-vsta
-               ;;
-       iris | iris4d)
-               basic_machine=mips-sgi
-               case $os in
-                   -irix*)
-                       ;;
-                   *)
-                       os=-irix4
-                       ;;
-               esac
-               ;;
-       isi68 | isi)
-               basic_machine=m68k-isi
-               os=-sysv
-               ;;
-       m68knommu)
-               basic_machine=m68k-unknown
-               os=-linux
-               ;;
-       m68knommu-*)
-               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       m88k-omron*)
-               basic_machine=m88k-omron
-               ;;
-       magnum | m3230)
-               basic_machine=mips-mips
-               os=-sysv
-               ;;
-       merlin)
-               basic_machine=ns32k-utek
-               os=-sysv
-               ;;
-       mingw32)
-               basic_machine=i386-pc
-               os=-mingw32
-               ;;
-       mingw32ce)
-               basic_machine=arm-unknown
-               os=-mingw32ce
-               ;;
-       miniframe)
-               basic_machine=m68000-convergent
-               ;;
-       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-               basic_machine=m68k-atari
-               os=-mint
-               ;;
-       mips3*-*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
-               ;;
-       mips3*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
-               ;;
-       monitor)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       morphos)
-               basic_machine=powerpc-unknown
-               os=-morphos
-               ;;
-       msdos)
-               basic_machine=i386-pc
-               os=-msdos
-               ;;
-       ms1-*)
-               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-               ;;
-       mvs)
-               basic_machine=i370-ibm
-               os=-mvs
-               ;;
-       ncr3000)
-               basic_machine=i486-ncr
-               os=-sysv4
-               ;;
-       netbsd386)
-               basic_machine=i386-unknown
-               os=-netbsd
-               ;;
-       netwinder)
-               basic_machine=armv4l-rebel
-               os=-linux
-               ;;
-       news | news700 | news800 | news900)
-               basic_machine=m68k-sony
-               os=-newsos
-               ;;
-       news1000)
-               basic_machine=m68030-sony
-               os=-newsos
-               ;;
-       news-3600 | risc-news)
-               basic_machine=mips-sony
-               os=-newsos
-               ;;
-       necv70)
-               basic_machine=v70-nec
-               os=-sysv
-               ;;
-       next | m*-next )
-               basic_machine=m68k-next
-               case $os in
-                   -nextstep* )
-                       ;;
-                   -ns2*)
-                     os=-nextstep2
-                       ;;
-                   *)
-                     os=-nextstep3
-                       ;;
-               esac
-               ;;
-       nh3000)
-               basic_machine=m68k-harris
-               os=-cxux
-               ;;
-       nh[45]000)
-               basic_machine=m88k-harris
-               os=-cxux
-               ;;
-       nindy960)
-               basic_machine=i960-intel
-               os=-nindy
-               ;;
-       mon960)
-               basic_machine=i960-intel
-               os=-mon960
-               ;;
-       nonstopux)
-               basic_machine=mips-compaq
-               os=-nonstopux
-               ;;
-       np1)
-               basic_machine=np1-gould
-               ;;
-       nsr-tandem)
-               basic_machine=nsr-tandem
-               ;;
-       op50n-* | op60c-*)
-               basic_machine=hppa1.1-oki
-               os=-proelf
-               ;;
-       openrisc | openrisc-*)
-               basic_machine=or32-unknown
-               ;;
-       os400)
-               basic_machine=powerpc-ibm
-               os=-os400
-               ;;
-       OSE68000 | ose68000)
-               basic_machine=m68000-ericsson
-               os=-ose
-               ;;
-       os68k)
-               basic_machine=m68k-none
-               os=-os68k
-               ;;
-       pa-hitachi)
-               basic_machine=hppa1.1-hitachi
-               os=-hiuxwe2
-               ;;
-       paragon)
-               basic_machine=i860-intel
-               os=-osf
-               ;;
-       parisc)
-               basic_machine=hppa-unknown
-               os=-linux
-               ;;
-       parisc-*)
-               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
-               os=-linux
-               ;;
-       pbd)
-               basic_machine=sparc-tti
-               ;;
-       pbb)
-               basic_machine=m68k-tti
-               ;;
-       pc532 | pc532-*)
-               basic_machine=ns32k-pc532
-               ;;
-       pc98)
-               basic_machine=i386-pc
-               ;;
-       pc98-*)
-               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium | p5 | k5 | k6 | nexgen | viac3)
-               basic_machine=i586-pc
-               ;;
-       pentiumpro | p6 | 6x86 | athlon | athlon_*)
-               basic_machine=i686-pc
-               ;;
-       pentiumii | pentium2 | pentiumiii | pentium3)
-               basic_machine=i686-pc
-               ;;
-       pentium4)
-               basic_machine=i786-pc
-               ;;
-       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pentium4-*)
-               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       pn)
-               basic_machine=pn-gould
-               ;;
-       power)  basic_machine=power-ibm
-               ;;
-       ppc)    basic_machine=powerpc-unknown
-               ;;
-       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppcle | powerpclittle | ppc-le | powerpc-little)
-               basic_machine=powerpcle-unknown
-               ;;
-       ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64)  basic_machine=powerpc64-unknown
-               ;;
-       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
-               basic_machine=powerpc64le-unknown
-               ;;
-       ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
-               ;;
-       ps2)
-               basic_machine=i386-ibm
-               ;;
-       pw32)
-               basic_machine=i586-unknown
-               os=-pw32
-               ;;
-       rdos)
-               basic_machine=i386-pc
-               os=-rdos
-               ;;
-       rom68k)
-               basic_machine=m68k-rom68k
-               os=-coff
-               ;;
-       rm[46]00)
-               basic_machine=mips-siemens
-               ;;
-       rtpc | rtpc-*)
-               basic_machine=romp-ibm
-               ;;
-       s390 | s390-*)
-               basic_machine=s390-ibm
-               ;;
-       s390x | s390x-*)
-               basic_machine=s390x-ibm
-               ;;
-       sa29200)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       sb1)
-               basic_machine=mipsisa64sb1-unknown
-               ;;
-       sb1el)
-               basic_machine=mipsisa64sb1el-unknown
-               ;;
-       sde)
-               basic_machine=mipsisa32-sde
-               os=-elf
-               ;;
-       sei)
-               basic_machine=mips-sei
-               os=-seiux
-               ;;
-       sequent)
-               basic_machine=i386-sequent
-               ;;
-       sh)
-               basic_machine=sh-hitachi
-               os=-hms
-               ;;
-       sh5el)
-               basic_machine=sh5le-unknown
-               ;;
-       sh64)
-               basic_machine=sh64-unknown
-               ;;
-       sparclite-wrs | simso-wrs)
-               basic_machine=sparclite-wrs
-               os=-vxworks
-               ;;
-       sps7)
-               basic_machine=m68k-bull
-               os=-sysv2
-               ;;
-       spur)
-               basic_machine=spur-unknown
-               ;;
-       st2000)
-               basic_machine=m68k-tandem
-               ;;
-       stratus)
-               basic_machine=i860-stratus
-               os=-sysv4
-               ;;
-       sun2)
-               basic_machine=m68000-sun
-               ;;
-       sun2os3)
-               basic_machine=m68000-sun
-               os=-sunos3
-               ;;
-       sun2os4)
-               basic_machine=m68000-sun
-               os=-sunos4
-               ;;
-       sun3os3)
-               basic_machine=m68k-sun
-               os=-sunos3
-               ;;
-       sun3os4)
-               basic_machine=m68k-sun
-               os=-sunos4
-               ;;
-       sun4os3)
-               basic_machine=sparc-sun
-               os=-sunos3
-               ;;
-       sun4os4)
-               basic_machine=sparc-sun
-               os=-sunos4
-               ;;
-       sun4sol2)
-               basic_machine=sparc-sun
-               os=-solaris2
-               ;;
-       sun3 | sun3-*)
-               basic_machine=m68k-sun
-               ;;
-       sun4)
-               basic_machine=sparc-sun
-               ;;
-       sun386 | sun386i | roadrunner)
-               basic_machine=i386-sun
-               ;;
-       sv1)
-               basic_machine=sv1-cray
-               os=-unicos
-               ;;
-       symmetry)
-               basic_machine=i386-sequent
-               os=-dynix
-               ;;
-       t3e)
-               basic_machine=alphaev5-cray
-               os=-unicos
-               ;;
-       t90)
-               basic_machine=t90-cray
-               os=-unicos
-               ;;
-       tic54x | c54x*)
-               basic_machine=tic54x-unknown
-               os=-coff
-               ;;
-       tic55x | c55x*)
-               basic_machine=tic55x-unknown
-               os=-coff
-               ;;
-       tic6x | c6x*)
-               basic_machine=tic6x-unknown
-               os=-coff
-               ;;
-       tile*)
-               basic_machine=tile-unknown
-               os=-linux-gnu
-               ;;
-       tx39)
-               basic_machine=mipstx39-unknown
-               ;;
-       tx39el)
-               basic_machine=mipstx39el-unknown
-               ;;
-       toad1)
-               basic_machine=pdp10-xkl
-               os=-tops20
-               ;;
-       tower | tower-32)
-               basic_machine=m68k-ncr
-               ;;
-       tpf)
-               basic_machine=s390x-ibm
-               os=-tpf
-               ;;
-       udi29k)
-               basic_machine=a29k-amd
-               os=-udi
-               ;;
-       ultra3)
-               basic_machine=a29k-nyu
-               os=-sym1
-               ;;
-       v810 | necv810)
-               basic_machine=v810-nec
-               os=-none
-               ;;
-       vaxv)
-               basic_machine=vax-dec
-               os=-sysv
-               ;;
-       vms)
-               basic_machine=vax-dec
-               os=-vms
-               ;;
-       vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
-               ;;
-       vxworks960)
-               basic_machine=i960-wrs
-               os=-vxworks
-               ;;
-       vxworks68)
-               basic_machine=m68k-wrs
-               os=-vxworks
-               ;;
-       vxworks29k)
-               basic_machine=a29k-wrs
-               os=-vxworks
-               ;;
-       w65*)
-               basic_machine=w65-wdc
-               os=-none
-               ;;
-       w89k-*)
-               basic_machine=hppa1.1-winbond
-               os=-proelf
-               ;;
-       xbox)
-               basic_machine=i686-pc
-               os=-mingw32
-               ;;
-       xps | xps100)
-               basic_machine=xps100-honeywell
-               ;;
-       ymp)
-               basic_machine=ymp-cray
-               os=-unicos
-               ;;
-       z8k-*-coff)
-               basic_machine=z8k-unknown
-               os=-sim
-               ;;
-       z80-*-coff)
-               basic_machine=z80-unknown
-               os=-sim
-               ;;
-       none)
-               basic_machine=none-none
-               os=-none
-               ;;
-
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-       w89k)
-               basic_machine=hppa1.1-winbond
-               ;;
-       op50n)
-               basic_machine=hppa1.1-oki
-               ;;
-       op60c)
-               basic_machine=hppa1.1-oki
-               ;;
-       romp)
-               basic_machine=romp-ibm
-               ;;
-       mmix)
-               basic_machine=mmix-knuth
-               ;;
-       rs6000)
-               basic_machine=rs6000-ibm
-               ;;
-       vax)
-               basic_machine=vax-dec
-               ;;
-       pdp10)
-               # there are many clones, so DEC is not a safe bet
-               basic_machine=pdp10-unknown
-               ;;
-       pdp11)
-               basic_machine=pdp11-dec
-               ;;
-       we32k)
-               basic_machine=we32k-att
-               ;;
-       sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-               basic_machine=sh-unknown
-               ;;
-       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-               basic_machine=sparc-sun
-               ;;
-       cydra)
-               basic_machine=cydra-cydrome
-               ;;
-       orion)
-               basic_machine=orion-highlevel
-               ;;
-       orion105)
-               basic_machine=clipper-highlevel
-               ;;
-       mac | mpw | mac-mpw)
-               basic_machine=m68k-apple
-               ;;
-       pmac | pmac-mpw)
-               basic_machine=powerpc-apple
-               ;;
-       *-unknown)
-               # Make sure to match an already-canonicalized machine name.
-               ;;
-       *)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-       *-digital*)
-               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
-               ;;
-       *-commodore*)
-               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
-               ;;
-       *)
-               ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
-       # -solaris* is a basic system type, with this one exception.
-       -solaris1 | -solaris1.*)
-               os=`echo $os | sed -e 's|solaris1|sunos4|'`
-               ;;
-       -solaris)
-               os=-solaris2
-               ;;
-       -svr4*)
-               os=-sysv4
-               ;;
-       -unixware*)
-               os=-sysv4.2uw
-               ;;
-       -gnu/linux*)
-               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
-               ;;
-       # First accept the basic system types.
-       # The portable systems comes first.
-       # Each alternative MUST END IN A *, to match a version number.
-       # -sysv* is not here because it comes later, after sysvr4.
-       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-             | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
-             | -kopensolaris* \
-             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* | -aros* \
-             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -openbsd* | -solidbsd* \
-             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* | -cegcc* \
-             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* \
-             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
-       # Remember, each alternative MUST END IN *, to match a version number.
-               ;;
-       -qnx*)
-               case $basic_machine in
-                   x86-* | i*86-*)
-                       ;;
-                   *)
-                       os=-nto$os
-                       ;;
-               esac
-               ;;
-       -nto-qnx*)
-               ;;
-       -nto*)
-               os=`echo $os | sed -e 's|nto|nto-qnx|'`
-               ;;
-       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
-             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
-               ;;
-       -mac*)
-               os=`echo $os | sed -e 's|mac|macos|'`
-               ;;
-       -linux-dietlibc)
-               os=-linux-dietlibc
-               ;;
-       -linux*)
-               os=`echo $os | sed -e 's|linux|linux-gnu|'`
-               ;;
-       -sunos5*)
-               os=`echo $os | sed -e 's|sunos5|solaris2|'`
-               ;;
-       -sunos6*)
-               os=`echo $os | sed -e 's|sunos6|solaris3|'`
-               ;;
-       -opened*)
-               os=-openedition
-               ;;
-        -os400*)
-               os=-os400
-               ;;
-       -wince*)
-               os=-wince
-               ;;
-       -osfrose*)
-               os=-osfrose
-               ;;
-       -osf*)
-               os=-osf
-               ;;
-       -utek*)
-               os=-bsd
-               ;;
-       -dynix*)
-               os=-bsd
-               ;;
-       -acis*)
-               os=-aos
-               ;;
-       -atheos*)
-               os=-atheos
-               ;;
-       -syllable*)
-               os=-syllable
-               ;;
-       -386bsd)
-               os=-bsd
-               ;;
-       -ctix* | -uts*)
-               os=-sysv
-               ;;
-       -nova*)
-               os=-rtmk-nova
-               ;;
-       -ns2 )
-               os=-nextstep2
-               ;;
-       -nsk*)
-               os=-nsk
-               ;;
-       # Preserve the version number of sinix5.
-       -sinix5.*)
-               os=`echo $os | sed -e 's|sinix|sysv|'`
-               ;;
-       -sinix*)
-               os=-sysv4
-               ;;
-        -tpf*)
-               os=-tpf
-               ;;
-       -triton*)
-               os=-sysv3
-               ;;
-       -oss*)
-               os=-sysv3
-               ;;
-       -svr4)
-               os=-sysv4
-               ;;
-       -svr3)
-               os=-sysv3
-               ;;
-       -sysvr4)
-               os=-sysv4
-               ;;
-       # This must come after -sysvr4.
-       -sysv*)
-               ;;
-       -ose*)
-               os=-ose
-               ;;
-       -es1800*)
-               os=-ose
-               ;;
-       -xenix)
-               os=-xenix
-               ;;
-       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-               os=-mint
-               ;;
-       -aros*)
-               os=-aros
-               ;;
-       -kaos*)
-               os=-kaos
-               ;;
-       -zvmoe)
-               os=-zvmoe
-               ;;
-       -dicos*)
-               os=-dicos
-               ;;
-       -none)
-               ;;
-       *)
-               # Get rid of the `-' at the beginning of $os.
-               os=`echo $os | sed 's/[^-]*-//'`
-               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
-               exit 1
-               ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system.  Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
-        score-*)
-               os=-elf
-               ;;
-        spu-*)
-               os=-elf
-               ;;
-       *-acorn)
-               os=-riscix1.2
-               ;;
-       arm*-rebel)
-               os=-linux
-               ;;
-       arm*-semi)
-               os=-aout
-               ;;
-        c4x-* | tic4x-*)
-               os=-coff
-               ;;
-       # This must come before the *-dec entry.
-       pdp10-*)
-               os=-tops20
-               ;;
-       pdp11-*)
-               os=-none
-               ;;
-       *-dec | vax-*)
-               os=-ultrix4.2
-               ;;
-       m68*-apollo)
-               os=-domain
-               ;;
-       i386-sun)
-               os=-sunos4.0.2
-               ;;
-       m68000-sun)
-               os=-sunos3
-               # This also exists in the configure program, but was not the
-               # default.
-               # os=-sunos4
-               ;;
-       m68*-cisco)
-               os=-aout
-               ;;
-        mep-*)
-               os=-elf
-               ;;
-       mips*-cisco)
-               os=-elf
-               ;;
-       mips*-*)
-               os=-elf
-               ;;
-       or32-*)
-               os=-coff
-               ;;
-       *-tti)  # must be before sparc entry or we get the wrong os.
-               os=-sysv3
-               ;;
-       sparc-* | *-sun)
-               os=-sunos4.1.1
-               ;;
-       *-be)
-               os=-beos
-               ;;
-       *-haiku)
-               os=-haiku
-               ;;
-       *-ibm)
-               os=-aix
-               ;;
-       *-knuth)
-               os=-mmixware
-               ;;
-       *-wec)
-               os=-proelf
-               ;;
-       *-winbond)
-               os=-proelf
-               ;;
-       *-oki)
-               os=-proelf
-               ;;
-       *-hp)
-               os=-hpux
-               ;;
-       *-hitachi)
-               os=-hiux
-               ;;
-       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-               os=-sysv
-               ;;
-       *-cbm)
-               os=-amigaos
-               ;;
-       *-dg)
-               os=-dgux
-               ;;
-       *-dolphin)
-               os=-sysv3
-               ;;
-       m68k-ccur)
-               os=-rtu
-               ;;
-       m88k-omron*)
-               os=-luna
-               ;;
-       *-next )
-               os=-nextstep
-               ;;
-       *-sequent)
-               os=-ptx
-               ;;
-       *-crds)
-               os=-unos
-               ;;
-       *-ns)
-               os=-genix
-               ;;
-       i370-*)
-               os=-mvs
-               ;;
-       *-next)
-               os=-nextstep3
-               ;;
-       *-gould)
-               os=-sysv
-               ;;
-       *-highlevel)
-               os=-bsd
-               ;;
-       *-encore)
-               os=-bsd
-               ;;
-       *-sgi)
-               os=-irix
-               ;;
-       *-siemens)
-               os=-sysv4
-               ;;
-       *-masscomp)
-               os=-rtu
-               ;;
-       f30[01]-fujitsu | f700-fujitsu)
-               os=-uxpv
-               ;;
-       *-rom68k)
-               os=-coff
-               ;;
-       *-*bug)
-               os=-coff
-               ;;
-       *-apple)
-               os=-macos
-               ;;
-       *-atari*)
-               os=-mint
-               ;;
-       *)
-               os=-none
-               ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-       *-unknown)
-               case $os in
-                       -riscix*)
-                               vendor=acorn
-                               ;;
-                       -sunos*)
-                               vendor=sun
-                               ;;
-                       -cnk*|-aix*)
-                               vendor=ibm
-                               ;;
-                       -beos*)
-                               vendor=be
-                               ;;
-                       -hpux*)
-                               vendor=hp
-                               ;;
-                       -mpeix*)
-                               vendor=hp
-                               ;;
-                       -hiux*)
-                               vendor=hitachi
-                               ;;
-                       -unos*)
-                               vendor=crds
-                               ;;
-                       -dgux*)
-                               vendor=dg
-                               ;;
-                       -luna*)
-                               vendor=omron
-                               ;;
-                       -genix*)
-                               vendor=ns
-                               ;;
-                       -mvs* | -opened*)
-                               vendor=ibm
-                               ;;
-                       -os400*)
-                               vendor=ibm
-                               ;;
-                       -ptx*)
-                               vendor=sequent
-                               ;;
-                       -tpf*)
-                               vendor=ibm
-                               ;;
-                       -vxsim* | -vxworks* | -windiss*)
-                               vendor=wrs
-                               ;;
-                       -aux*)
-                               vendor=apple
-                               ;;
-                       -hms*)
-                               vendor=hitachi
-                               ;;
-                       -mpw* | -macos*)
-                               vendor=apple
-                               ;;
-                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-                               vendor=atari
-                               ;;
-                       -vos*)
-                               vendor=stratus
-                               ;;
-               esac
-               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
-               ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/src/configure.ac b/src/configure.ac
deleted file mode 100644 (file)
index 58ba71d..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-#                                               -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.53)
-AC_INIT(ejabberd, m4_esyscmd([grep -o -E "\{vsn,.\".*\"\}" ejabberd.app | cut -d \" -f 2 | tr -d '\n']), [ejabberd@process-one.net], [ejabberd])
-
-# Checks for programs.
-AC_PROG_CC
-AC_PROG_MAKE_SET
-
-if test "x$GCC" = "xyes"; then
-    CFLAGS="$CFLAGS -Wall"
-fi
-
-#locating erlang
-AM_WITH_ERLANG
-#locating iconv
-AM_ICONV
-#locating libexpat
-AM_WITH_EXPAT
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-
-# Check Erlang headers are installed
-#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
-
-# Change default prefix
-AC_PREFIX_DEFAULT(/)
-
-# Checks for library functions.
-AC_FUNC_MALLOC
-AC_HEADER_STDC
-
-AC_MOD_ENABLE(mod_irc, yes)
-AC_MOD_ENABLE(mod_muc, yes)
-AC_MOD_ENABLE(mod_proxy65, yes)
-AC_MOD_ENABLE(mod_pubsub, yes)
-AC_MOD_ENABLE(eldap, yes)
-AC_MOD_ENABLE(odbc, no)
-AC_MOD_ENABLE(tls, yes)
-AC_MOD_ENABLE(web, yes)
-
-AC_MOD_ENABLE(ejabberd_zlib, yes)
-#locating zlib
-AM_WITH_ZLIB
-
-AC_MOD_ENABLE(pam, no)
-#locating PAM
-AM_WITH_PAM
-
-AC_ARG_ENABLE(hipe,
-[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
-[case "${enableval}" in
-  yes) hipe=true ;;
-  no)  hipe=false ;;
-  *) AC_MSG_ERROR(bad value ${enableval} for --enable-hipe) ;;
-esac],[hipe=false])
-AC_SUBST(hipe)
-
-AC_ARG_ENABLE(roster_gateway_workaround,
-[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
-[case "${enableval}" in
-  yes) roster_gateway_workaround=true ;;
-  no)  roster_gateway_workaround=false ;;
-  *) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
-esac],[roster_gateway_workaround=false])
-AC_SUBST(roster_gateway_workaround)
-
-AC_ARG_ENABLE(mssql,
-[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
-[case "${enableval}" in
-  yes) db_type=mssql ;;
-  no)  db_type=generic ;;
-  *) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
-esac],[db_type=generic])
-AC_SUBST(db_type)
-
-AC_ARG_ENABLE(transient_supervisors,
-[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: yes)])],
-[case "${enableval}" in
-  yes) transient_supervisors=true ;;
-  no)  transient_supervisors=false ;;
-  *) AC_MSG_ERROR(bad value ${enableval} for --enable-transient_supervisors) ;;
-esac],[transient_supervisors=true])
-AC_SUBST(transient_supervisors)
-
-AC_ARG_ENABLE(full_xml,
-[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
-[case "${enableval}" in
-  yes) full_xml=true ;;
-  no)  full_xml=false ;;
-  *) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;;
-esac],[full_xml=false])
-AC_SUBST(full_xml)
-
-AC_ARG_ENABLE(nif,
-[AC_HELP_STRING([--enable-nif], [replace some functions with C equivalents. Requires Erlang R13B04 or higher (default: no)])],
-[case "${enableval}" in
-  yes) nif=true ;;
-  no)  nif=false ;;
-  *) AC_MSG_ERROR(bad value ${enableval} for --enable-nif) ;;
-esac],[nif=false])
-AC_SUBST(nif)
-
-AC_CONFIG_FILES([Makefile
-                 $make_mod_irc
-                 $make_mod_muc
-                 $make_mod_pubsub
-                 $make_mod_proxy65
-                 $make_eldap
-                 $make_pam
-                 $make_web
-                 mysql/Makefile
-                 pgsql/Makefile
-                 stringprep/Makefile
-                 stun/Makefile
-                 $make_tls
-                 $make_odbc
-                 $make_ejabberd_zlib])
-#openssl
-AM_WITH_OPENSSL
-# If ssl is kerberized it need krb5.h
-# On RedHat and OpenBSD, krb5.h is in an unsual place:
-KRB5_INCLUDE="`krb5-config --cflags 2>/dev/null`"
-if test -n "$KRB5_INCLUDE" ; then
-        CPPFLAGS="$CPPFLAGS $KRB5_INCLUDE"
-else
-        #         For RedHat                                  For BSD
-        for D in /usr/kerberos/include /usr/include/kerberos /usr/include/kerberosV
-        do
-                if test -d $D ; then
-                        CPPFLAGS="$CPPFLAGS -I$D"
-                fi
-        done
-fi
-AC_CHECK_HEADER(krb5.h,,)
-
-ENABLEUSER=""
-AC_ARG_ENABLE(user,
-  [AS_HELP_STRING([--enable-user[[[[=USER]]]]], [allow this system user to start ejabberd (default: no)])],
-  [case "${enableval}" in
-     yes) ENABLEUSER=`whoami` ;;
-     no) ENABLEUSER="" ;;
-     *) ENABLEUSER=$enableval
-   esac],
-  [])
-if test "$ENABLEUSER" != ""; then
-  echo "allow this system user to start ejabberd: $ENABLEUSER"
-  AC_SUBST([INSTALLUSER], [$ENABLEUSER])
-fi
-
-AC_CHECK_HEADER(openssl/md2.h, md2=true, md2=false)
-AC_SUBST(md2)
-
-AC_CANONICAL_SYSTEM
-#AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$target")
-#AC_SUBST(target_os)
-
-
-case "$target_os" in
-    *darwin*)
-       echo "Target OS is 'Darwin'"
-       AC_LANG(Erlang)
-       AC_RUN_IFELSE(
-           [AC_LANG_PROGRAM([],[dnl
-            halt(case erlang:system_info(wordsize) of
-            8 -> 0; 4 -> 1 end)])],
-           [AC_MSG_NOTICE(found 64-bit Erlang)
-            CBIT=-m64],
-           [AC_MSG_NOTICE(found 32-bit Erlang)
-            CBIT=-m32])
-       ;;
-    *)        
-       echo "Target OS is '$target_os'"
-       CBIT=""
-       ;;
-esac
-CFLAGS="$CFLAGS $CBIT"
-LD_SHARED="$LD_SHARED $CBIT"
-echo "CBIT is set to '$CBIT'"
-
-AC_OUTPUT
index 87b7bc20878716f15063a1aebd4eb440614ca93f..6f0b1dd4e3a07924bcb943cf6fee4903a8ec307c 100644 (file)
@@ -30,6 +30,7 @@
 -export([start/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 start() ->
     Static = case os:getenv("arg") of
index 0672267b2f3a5c528053818c0b943489d7e15d05..6c847bb526c7a9c552cbec99adcd56f29b9d0086 100644 (file)
@@ -32,6 +32,7 @@
         server_new/7, server_start/3, server_step/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %%
 -export_type([
index 3bb88431b3c647fc4450ee7a407d336ad347e5ec..70e9400c073038512b1ed3414a582b561b05658a 100644 (file)
@@ -31,6 +31,7 @@
 -export([start/1, stop/0, mech_new/4, mech_step/2, parse/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -behaviour(cyrsasl).
 
index ee68bed1efce0fbdf7773e7b7cb5154bbbb1497c..7338ea7bb2fb3b9080c36dcbc3ea7fe4da8b2615 100644 (file)
@@ -31,6 +31,7 @@
 -export([start/1, stop/0, mech_new/4, mech_step/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
diff --git a/src/dynamic_compile.erl b/src/dynamic_compile.erl
deleted file mode 100644 (file)
index 1fe2dca..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-%% Copyright (c) 2007
-%%          Mats Cronqvist <mats.cronqvist@ericsson.com>
-%%          Chris Newcombe <chris.newcombe@gmail.com> 
-%%          Jacob Vorreuter <jacob.vorreuter@gmail.com>
-%% 
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%% 
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%% 
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-
-%%%-------------------------------------------------------------------
-%%% File : dynamic_compile.erl
-%%% Description :
-%%% Authors : Mats Cronqvist <mats.cronqvist@ericsson.com>
-%%%           Chris Newcombe <chris.newcombe@gmail.com> 
-%%%           Jacob Vorreuter <jacob.vorreuter@gmail.com>
-%%% TODO :
-%%% - add support for limit include-file depth (and prevent circular references)
-%%%   prevent circular macro expansion set FILE correctly when -module() is found
-%%% -include_lib support $ENVVAR in include filenames
-%%%  substitute-stringize (??MACRO)
-%%% -undef/-ifdef/-ifndef/-else/-endif
-%%% -file(File, Line)
-%%%-------------------------------------------------------------------
--module(dynamic_compile).
-
-%% API
--export([from_string/1, from_string/2]).
-
--import(lists, [reverse/1, keyreplace/4]).
-
-%%====================================================================
-%% API
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function:
-%% Description:
-%%   Returns a binary that can be used with
-%%           code:load_binary(Module, ModuleFilenameForInternalRecords, Binary).
-%%--------------------------------------------------------------------
-from_string(CodeStr) ->
-    from_string(CodeStr, []).
-
-% takes Options as for compile:forms/2
-from_string(CodeStr, CompileFormsOptions) ->
-    %% Initialise the macro dictionary with the default predefined macros,
-    %% (adapted from epp.erl:predef_macros/1
-    Filename = "compiled_from_string",
-    %%Machine  = list_to_atom(erlang:system_info(machine)),
-    Ms0    = dict:new(),
-    % Ms1    = dict:store('FILE',          {[], "compiled_from_string"}, Ms0),
-    % Ms2    = dict:store('LINE',          {[], 1}, Ms1),  % actually we might add special code for this
-    % Ms3    = dict:store('MODULE',        {[], undefined},              Ms2),
-    % Ms4    = dict:store('MODULE_STRING', {[], undefined},              Ms3),
-    % Ms5    = dict:store('MACHINE',       {[], Machine},                Ms4),
-    % InitMD = dict:store(Machine,         {[], true},                   Ms5),
-    InitMD = Ms0,
-
-    %% From the docs for compile:forms:
-    %%    When encountering an -include or -include_dir directive, the compiler searches for header files in the following directories:
-    %%      1. ".", the current working directory of the file server;
-    %%      2. the base name of the compiled file;
-    %%      3. the directories specified using the i option. The directory specified last is searched first.
-    %% In this case, #2 is meaningless.
-    IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])],
-    {RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath),
-    Forms = reverse(RevForms),
-
-    %% note: 'binary' is forced as an implicit option, whether it is provided or not.
-    case compile:forms(Forms, CompileFormsOptions) of
-        {ok, ModuleName, CompiledCodeBinary} when is_binary(CompiledCodeBinary) ->
-            {ModuleName, CompiledCodeBinary};
-        {ok, ModuleName, CompiledCodeBinary, []} when is_binary(CompiledCodeBinary) ->  % empty warnings list
-            {ModuleName, CompiledCodeBinary};
-        {ok, _ModuleName, _CompiledCodeBinary, Warnings} ->
-            throw({?MODULE, warnings, Warnings});
-        Other ->
-            throw({?MODULE, compile_forms, Other})
-    end.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-%%% Code from Mats Cronqvist
-%%% See http://www.erlang.org/pipermail/erlang-questions/2007-March/025507.html
-%%%## 'scan_and_parse'
-%%%
-%%% basically we call the OTP scanner and parser (erl_scan and
-%%% erl_parse) line-by-line, but check each scanned line for (or
-%%% definitions of) macros before parsing.
-%% returns {ReverseForms, FinalMacroDict}
-scan_and_parse([], _CurrFilename, _CurrLine, RevForms, MacroDict, _IncludeSearchPath) ->
-    {RevForms, MacroDict};
-
-scan_and_parse(RemainingText, CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath) ->
-    case scanner(RemainingText, CurrLine, MacroDict) of
-           {tokens, NLine, NRemainingText, Toks} ->
-               {ok, Form} = erl_parse:parse_form(Toks),
-               scan_and_parse(NRemainingText, CurrFilename, NLine, [Form | RevForms], MacroDict, IncludeSearchPath);
-           {macro, NLine, NRemainingText, NMacroDict} ->
-               scan_and_parse(NRemainingText, CurrFilename, NLine, RevForms,NMacroDict, IncludeSearchPath);
-        {include, NLine, NRemainingText, IncludeFilename} ->
-            IncludeFileRemainingTextents = read_include_file(IncludeFilename, IncludeSearchPath),
-            %%io:format("include file ~p contents: ~n~p~nRemainingText = ~p~n", [IncludeFilename,IncludeFileRemainingTextents, RemainingText]),
-            %% Modify the FILE macro to reflect the filename
-            %%IncludeMacroDict = dict:store('FILE', {[],IncludeFilename}, MacroDict),
-            IncludeMacroDict = MacroDict,
-
-            %% Process the header file (inc. any nested header files)
-            {RevIncludeForms, IncludedMacroDict} = scan_and_parse(IncludeFileRemainingTextents, IncludeFilename, 1, [], IncludeMacroDict, IncludeSearchPath),
-            %io:format("include file results = ~p~n", [R]),
-            %% Restore the FILE macro in the NEW MacroDict (so we keep any macros defined in the header file)
-            %%NMacroDict = dict:store('FILE', {[],CurrFilename}, IncludedMacroDict),
-            NMacroDict = IncludedMacroDict,
-
-            %% Continue with the original file
-               scan_and_parse(NRemainingText, CurrFilename, NLine, RevIncludeForms ++ RevForms, NMacroDict, IncludeSearchPath);
-        done ->
-               scan_and_parse([], CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath)
-    end.
-
-scanner(Text, Line, MacroDict) ->
-    case erl_scan:tokens([],Text,Line) of
-        {done, {ok,Toks,NLine}, LeftOverChars} ->
-            case pre_proc(Toks, MacroDict) of
-                {tokens,  NToks}      -> {tokens,  NLine, LeftOverChars, NToks};
-                {macro,   NMacroDict} -> {macro,   NLine, LeftOverChars, NMacroDict};
-                {include, Filename}   -> {include, NLine, LeftOverChars, Filename}
-            end;
-        {more, _Continuation} ->
-            %% This is supposed to mean "term is not yet complete" (i.e. a '.' has
-            %% not been reached yet).
-            %% However, for some bizarre reason we also get this if there is a comment after the final '.' in a file.
-            %% So we check to see if Text only consists of comments.
-            case is_only_comments(Text) of
-                true  ->
-                    done;
-                false ->
-                    throw({incomplete_term, Text, Line})
-            end
-    end.
-
-is_only_comments(Text) -> is_only_comments(Text, not_in_comment).
-
-is_only_comments([],       _)              -> true;
-is_only_comments([$   |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
-is_only_comments([$\t |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
-is_only_comments([$\n |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
-is_only_comments([$%  |T], not_in_comment) -> is_only_comments(T, in_comment);     % found start of a comment
-is_only_comments(_,        not_in_comment) -> false;
-% found any significant char NOT in a comment
-is_only_comments([$\n |T], in_comment)     -> is_only_comments(T, not_in_comment); % found end of a comment
-is_only_comments([_   |T], in_comment)     -> is_only_comments(T, in_comment).     % skipping over in-comment chars
-
-%%%## 'pre-proc'
-%%%
-%%% have to implement a subset of the pre-processor, since epp insists
-%%% on running on a file.
-%%% only handles 2 cases;
-%% -define(MACRO, something).
-%% -define(MACRO(VAR1,VARN),{stuff,VAR1,more,stuff,VARN,extra,stuff}).
-pre_proc([{'-',_},{atom,_,define},{'(',_},{_,_,Name}|DefToks],MacroDict) ->
-    false = dict:is_key(Name, MacroDict),
-    case DefToks of
-       [{',',_} | Macro] ->
-           {macro, dict:store(Name, {[], macro_body_def(Macro, [])},  MacroDict)};
-       [{'(',_} | Macro] ->
-           {macro, dict:store(Name, macro_params_body_def(Macro, []), MacroDict)}
-    end;
-
-pre_proc([{'-',_}, {atom,_,include}, {'(',_}, {string,_,Filename}, {')',_}, {dot,_}], _MacroDict) ->
-    {include, Filename};
-
-pre_proc(Toks,MacroDict) ->
-    {tokens, subst_macros(Toks, MacroDict)}.
-
-macro_params_body_def([{')',_},{',',_} | Toks], RevParams) ->
-    {reverse(RevParams), macro_body_def(Toks, [])};
-macro_params_body_def([{var,_,Param} | Toks], RevParams) ->
-    macro_params_body_def(Toks, [Param | RevParams]);
-macro_params_body_def([{',',_}, {var,_,Param} | Toks], RevParams) ->
-    macro_params_body_def(Toks, [Param | RevParams]).
-
-macro_body_def([{')',_}, {dot,_}], RevMacroBodyToks) ->
-    reverse(RevMacroBodyToks);
-macro_body_def([Tok|Toks], RevMacroBodyToks) ->
-    macro_body_def(Toks, [Tok | RevMacroBodyToks]).
-
-subst_macros(Toks, MacroDict) ->
-    reverse(subst_macros_rev(Toks, MacroDict, [])).
-
-%% returns a reversed list of tokes
-subst_macros_rev([{'?',_}, {_,LineNum,'LINE'} | Toks], MacroDict, RevOutToks) ->
-    %% special-case for ?LINE, to avoid creating a new MacroDict for every line in the source file
-    subst_macros_rev(Toks, MacroDict, [{integer,LineNum,LineNum}] ++ RevOutToks);
-
-subst_macros_rev([{'?',_}, {_,_,Name}, {'(',_} = Paren | Toks], MacroDict, RevOutToks) ->
-    case dict:fetch(Name, MacroDict) of
-        {[], MacroValue} ->
-            %% This macro does not have any vars, so ignore the fact that the invocation is followed by "(...stuff"
-            %% Recursively expand any macro calls inside this macro's value
-            %% TODO: avoid infinite expansion due to circular references (even indirect ones)
-            RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []),
-            subst_macros_rev([Paren|Toks], MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks);
-        ParamsAndBody ->
-            %% This macro does have vars.
-            %% Collect all of the passe arguments, in an ordered list
-            {NToks, Arguments} = subst_macros_get_args(Toks, []),
-            %% Expand the varibles
-            ExpandedParamsToks = subst_macros_subst_args_for_vars(ParamsAndBody, Arguments),
-            %% Recursively expand any macro calls inside this macro's value
-            %% TODO: avoid infinite expansion due to circular references (even indirect ones)
-            RevExpandedOtherMacrosToks = subst_macros_rev(ExpandedParamsToks, MacroDict, []),
-            subst_macros_rev(NToks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks)
-    end;
-
-subst_macros_rev([{'?',_}, {_,_,Name} | Toks], MacroDict, RevOutToks) ->
-    %% This macro invocation does not have arguments.
-    %% Therefore the definition should not have parameters
-    {[], MacroValue} = dict:fetch(Name, MacroDict),
-
-    %% Recursively expand any macro calls inside this macro's value
-    %% TODO: avoid infinite expansion due to circular references (even indirect ones)
-    RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []),
-    subst_macros_rev(Toks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks);
-
-subst_macros_rev([Tok|Toks], MacroDict,  RevOutToks) ->
-subst_macros_rev(Toks, MacroDict, [Tok|RevOutToks]);
-subst_macros_rev([], _MacroDict, RevOutToks) -> RevOutToks.
-
-subst_macros_get_args([{')',_} | Toks], RevArgs) ->
-    {Toks, reverse(RevArgs)};
-subst_macros_get_args([{',',_}, {var,_,ArgName} | Toks], RevArgs) ->
-    subst_macros_get_args(Toks, [ArgName| RevArgs]);
-subst_macros_get_args([{var,_,ArgName} | Toks], RevArgs) ->
-    subst_macros_get_args(Toks, [ArgName | RevArgs]).
-
-subst_macros_subst_args_for_vars({[], BodyToks}, []) ->
-    BodyToks;
-subst_macros_subst_args_for_vars({[Param | Params], BodyToks}, [Arg|Args]) ->
-    NBodyToks = keyreplace(Param, 3, BodyToks, {var,1,Arg}),
-    subst_macros_subst_args_for_vars({Params, NBodyToks}, Args).
-
-read_include_file(Filename, IncludeSearchPath) ->
-    case file:path_open(IncludeSearchPath, Filename, [read, raw, binary]) of
-        {ok, IoDevice, FullName} ->
-            {ok, Data} = file:read(IoDevice, filelib:file_size(FullName)),
-            file:close(IoDevice),
-            binary_to_list(Data);
-        {error, Reason} ->
-            throw({failed_to_read_include_file, Reason, Filename, IncludeSearchPath})
-    end.
\ No newline at end of file
diff --git a/src/ejabberd.app b/src/ejabberd.app
deleted file mode 100644 (file)
index 9aeca5b..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-%% $Id$
-
-{application, ejabberd,
- [{description, "ejabberd"},
-  {vsn, "13.03-beta2"},
-  {modules, [acl,
-            adhoc,
-            configure,
-            cyrsasl_anonymous,
-            cyrsasl,
-            cyrsasl_digest,
-            cyrsasl_plain,
-            cyrsasl_scram,
-            ejabberd_admin,
-            ejabberd_app,
-            ejabberd_auth_anonymous,
-            ejabberd_auth,
-            ejabberd_auth_external,
-            ejabberd_auth_internal,
-            ejabberd_auth_ldap,
-            ejabberd_auth_odbc,
-            ejabberd_auth_pam,
-            ejabberd,
-            ejabberd_c2s,
-            ejabberd_c2s_config,
-            ejabberd_config,
-            ejabberd_ctl,
-            ejabberd_frontend_socket,
-            ejabberd_hooks,
-            ejabberd_http,
-            ejabberd_http_bind,
-            ejabberd_http_poll,
-            ejabberd_listener,
-            ejabberd_local,
-            ejabberd_logger_h,
-            ejabberd_loglevel,
-            ejabberd_node_groups,
-            ejabberd_rdbms,
-            ejabberd_receiver,
-            ejabberd_router,
-            ejabberd_s2s,
-            ejabberd_s2s_in,
-            ejabberd_s2s_out,
-            ejabberd_service,
-            ejabberd_sm,
-            ejabberd_socket,
-            ejabberd_sup,
-            ejabberd_system_monitor,
-            ejabberd_tmp_sup,
-            ejabberd_update,
-            ejabberd_web_admin,
-            ejabberd_web,
-            ejabberd_zlib,
-            ejd2odbc,
-            eldap,
-            eldap_filter,
-            eldap_pool,
-            eldap_utils,
-            'ELDAPv3',
-            extauth,
-            gen_iq_handler,
-            gen_mod,
-            gen_pubsub_node,
-            gen_pubsub_nodetree,
-            iconv,
-            idna,
-            jd2ejd,
-            jlib,
-            mod_adhoc,
-            mod_announce,
-            mod_caps,
-            mod_configure2,
-            mod_configure,
-            mod_disco,
-            mod_echo,
-            mod_http_bind,
-            mod_http_fileserver,
-            mod_irc,
-            mod_irc_connection,
-            mod_last,
-            mod_muc,
-            mod_muc_log,
-            mod_muc_room,
-            mod_offline,
-            mod_privacy,
-            mod_private,
-            mod_proxy65,
-            mod_proxy65_lib,
-            mod_proxy65_service,
-            mod_proxy65_sm,
-            mod_proxy65_stream,
-            mod_pubsub,
-            mod_register,
-            mod_roster,
-            mod_service_log,
-            mod_shared_roster,
-            mod_stats,
-            mod_time,
-            mod_vcard,
-            mod_vcard_ldap,
-            mod_version,
-            node_buddy,
-            node_club,
-            node_default,
-            node_dispatch,
-            node_pep,
-            node_private,
-            node_public,
-            nodetree_default,
-            nodetree_virtual,
-            p1_fsm,
-            p1_mnesia,
-            p1_prof,
-            randoms,
-            sha,
-            shaper,
-            stringprep,
-            stringprep_sup,
-            tls,
-            translate,
-            xml,
-            xml_stream,
-            'XmppAddr'
-           ]},
-  {registered, [ejabberd,
-               ejabberd_sup,
-               ejabberd_auth,
-               ejabberd_router,
-               ejabberd_sm,
-               ejabberd_s2s,
-               ejabberd_local,
-               ejabberd_listeners,
-               ejabberd_iq_sup,
-               ejabberd_service_sup,
-               ejabberd_s2s_out_sup,
-               ejabberd_s2s_in_sup,
-               ejabberd_c2s_sup,
-               ejabberd_mod_roster,
-               ejabberd_mod_echo,
-               ejabberd_mod_pubsub,
-               ejabberd_mod_irc,
-               ejabberd_mod_muc,
-               ejabberd_offline,
-               random_generator
-              ]},
-  {applications, [kernel, stdlib]},
-  {env, []},
-  {mod, {ejabberd_app, []}}]}.
-
-
-%% Local Variables:
-%% mode: erlang
-%% End:
-%% vim: set filetype=erlang tabstop=8:
diff --git a/src/ejabberd.app.src.in b/src/ejabberd.app.src.in
new file mode 100644 (file)
index 0000000..4b08648
--- /dev/null
@@ -0,0 +1,16 @@
+%% $Id$
+
+{application, ejabberd,
+ [{description, "@PACKAGE_NAME@"},
+  {vsn, "@PACKAGE_VERSION@"},
+  {modules, []},
+  {registered, []},
+  {applications, [kernel, stdlib]},
+  {env, []},
+  {mod, {ejabberd_app, []}}]}.
+
+
+%% Local Variables:
+%% mode: erlang
+%% End:
+%% vim: set filetype=erlang tabstop=8:
index 258662473313fd3c0a252450c3d66a9dda054524..7b83f19a1460bf7c1eb24c55b6c7b3cf1a5f321e 100644 (file)
 -module(ejabberd).
 -author('alexey@process-one.net').
 
--export([start/0, stop/0,
-        get_pid_file/0,
-        get_so_path/0, get_bin_path/0]).
+-export([start/0, stop/0, start_app/1,
+        get_pid_file/0]).
+
+-include("logger.hrl").
 
 start() ->
     %%ejabberd_cover:start(),
@@ -39,32 +40,6 @@ stop() ->
     application:stop(ejabberd).
     %%ejabberd_cover:stop().
 
-get_so_path() ->
-    case os:getenv("EJABBERD_SO_PATH") of
-       false ->
-           case code:priv_dir(ejabberd) of
-               {error, _} ->
-                   ".";
-               Path ->
-                   filename:join([Path, "lib"])
-           end;
-       Path ->
-           Path
-    end.
-
-get_bin_path() ->
-    case os:getenv("EJABBERD_BIN_PATH") of
-       false ->
-           case code:priv_dir(ejabberd) of
-               {error, _} ->
-                   ".";
-               Path ->
-                   filename:join([Path, "bin"])
-           end;
-       Path ->
-           Path
-    end.
-
 %% @spec () -> false | string()
 get_pid_file() ->
     case os:getenv("EJABBERD_PID_PATH") of
@@ -75,3 +50,28 @@ get_pid_file() ->
        Path ->
            Path
     end.
+
+start_app(App) when not is_list(App) ->
+    start_app([App]);
+start_app([App|Apps]) ->
+    case application:start(App) of
+        ok ->
+            start_app(Apps);
+        {error, {already_started, _}} ->
+            start_app(Apps);
+        {error, {not_started, DepApp}} ->
+            case lists:member(DepApp, [App|Apps]) of
+                true ->
+                    ?CRITICAL_MSG("failed to start application '~p': "
+                                  "circular dependency on '~p' detected",
+                                  [App, DepApp]),
+                    erlang:error(application_start_failed);
+                false ->
+                    start_app([DepApp,App|Apps])
+            end;
+        Err ->
+            ?CRITICAL_MSG("failed to start application '~p': ~p", [App, Err]),
+            erlang:error(application_start_failed)
+    end;
+start_app([]) ->
+    ok.
index 9fa95abf680ca30ac11f548e2f11c854235184fa..5218d588a70726c715ff16d818cfc0de8446b16f 100644 (file)
@@ -53,6 +53,7 @@
        ]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("ejabberd_commands.hrl").
 
 start() ->
@@ -96,7 +97,7 @@ commands() ->
                        result = {res, rescode}},
      #ejabberd_commands{name = get_loglevel, tags = [logs, server],
                        desc = "Get the current loglevel",
-                       module = ejabberd_loglevel, function = get,
+                       module = ejabberd_logger, function = get,
                        args = [],
                         result = {leveltuple, {tuple, [{levelnumber, integer},
                                                        {levelatom, atom},
@@ -240,27 +241,7 @@ status() ->
 
 reopen_log() ->
     ejabberd_hooks:run(reopen_log_hook, []),
-    %% TODO: Use the Reopen log API for logger_h ?
-    ejabberd_logger_h:reopen_log(),
-    case application:get_env(sasl,sasl_error_logger) of
-       {ok, {file, SASLfile}} ->
-           error_logger:delete_report_handler(sasl_report_file_h),
-           ejabberd_logger_h:rotate_log(SASLfile),
-           error_logger:add_report_handler(sasl_report_file_h,
-               {SASLfile, get_sasl_error_logger_type()});
-       _ -> false
-       end,
-    ok.
-
-%% Function copied from Erlang/OTP lib/sasl/src/sasl.erl which doesn't export it
-get_sasl_error_logger_type () ->
-    case application:get_env (sasl, errlog_type) of
-       {ok, error} -> error;
-       {ok, progress} -> progress;
-       {ok, all} -> all;
-       {ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}});
-       _ -> all
-    end.
+    ejabberd_logger:reopen_log().
 
 %%%
 %%% Stop Kindly
index 393d7afb2d17d8dc06807fca3a049bf3820cab12..b9a48bc4202ed26edb05f2091799cbf22e76babf 100644 (file)
 -export([start_modules/0,start/2, get_log_path/0, prep_stop/1, stop/1, init/0]).
 
 -include("ejabberd.hrl").
-
+-include("logger.hrl").
 
 %%%
 %%% Application API
 %%%
 
 start(normal, _Args) ->
-    ejabberd_loglevel:set(4),
+    maybe_start_lager(),
+    ejabberd_logger:set(4),
     write_pid_file(),
-    application:start(sasl),
+    start_apps(),
     randoms:start(),
     db_init(),
-    sha:start(),
-    stringprep_sup:start_link(),
-    xml:start(),
     start(),
     translate:start(),
     acl:start(),
@@ -103,20 +101,13 @@ init() ->
     %erlang:system_flag(fullsweep_after, 0),
     %error_logger:logfile({open, ?LOG_PATH}),
     LogPath = get_log_path(),
-    error_logger:add_report_handler(ejabberd_logger_h, LogPath),
-    erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv),
-    case erl_ddll:load_driver(ejabberd:get_so_path(), expat_erl) of
-       ok -> ok;
-       {error, already_loaded} -> ok
-    end,
-    Port = open_port({spawn, "expat_erl"}, [binary]),
-    loop(Port).
-
+    ejabberd_logger:set_logfile(LogPath),
+    loop().
 
-loop(Port) ->
+loop() ->
     receive
        _ ->
-           loop(Port)
+           loop()
     end.
 
 db_init() ->
@@ -245,3 +236,26 @@ delete_pid_file() ->
        PidFilename ->
            file:delete(PidFilename)
     end.
+
+
+-ifdef(LAGER).
+
+maybe_start_lager() ->
+    lager:start().
+
+-else.
+
+maybe_start_lager() ->
+    ok.
+
+-endif.
+
+
+start_apps() ->
+    ejabberd:start_app(sasl),
+    ejabberd:start_app(ssl),
+    ejabberd:start_app(p1_tls),
+    ejabberd:start_app(p1_xml),
+    ejabberd:start_app(p1_stringprep),
+    ejabberd:start_app(p1_zlib),
+    ejabberd:start_app(p1_cache_tab).
index 298cdf1ebee364b5d13d53fd8c830f6c88879cd7..a82c343e4ce923886fe5993587bdefe39edcd9ac 100644 (file)
@@ -46,6 +46,7 @@
 -export([auth_modules/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %%%----------------------------------------------------------------------
 %%% API
index c19effabef1ca921717cc19fa79e8d6b8569c167..d8101efc4fc72c3aa931ea4bfac2e84bec2339e1 100644 (file)
@@ -49,6 +49,7 @@
         plain_password_required/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 8ae6a1df52131731abfe08194cc4c5ad49772ae4..2d1bb7cb90c74fb4d3c4d9ec1b33927a20889dbf 100644 (file)
@@ -42,6 +42,7 @@
         plain_password_required/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %%%----------------------------------------------------------------------
 %%% API
index b3587e2115a776543d9aa82d6f4a22a81d997fa0..f66b09c88b6479bca9874523f140933a950a1728 100644 (file)
@@ -42,6 +42,7 @@
         plain_password_required/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
                  password = <<"">> :: binary() | scram() | '_'}).
index 998f21215b8b2a32842b23cdd99fc8ae23722b12..1baf438874ea79ea44e4392595e7294110e18e3c 100644 (file)
         plain_password_required/0]).
 
 -include("ejabberd.hrl").
-%% Unused callbacks.
-%% -----
+-include("logger.hrl").
 
--include("eldap/eldap.hrl").
+-include("eldap.hrl").
 
 -record(state,
        {host = <<"">>          :: binary(),
index 7a2e90e02f2a224954852d3025490fef0d5e42ec..a1841f3d1838a11b2fb186acfb6b0748de52cb3d 100644 (file)
@@ -42,6 +42,7 @@
         plain_password_required/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %%%----------------------------------------------------------------------
 %%% API
index a1400fe8e490910e6a889444b29628a33b8ac71a..c812084942389693749e5a63e0a193fc203f355f 100644 (file)
         plain_password_required/0]).
 
 start(_Host) ->
-    case epam:start() of
-      {ok, _} -> ok;
-      {error, {already_started, _}} -> ok;
-      Err -> Err
-    end.
+    ejabberd:start_app(p1_pam).
 
 set_password(_User, _Server, _Password) ->
     {error, not_allowed}.
index dab8fa546a2b51a9e322971bf244e8038305a9b9..ad6b1b55c15bb1bf306cd6c22fd221b3ab4cfcf7 100644 (file)
@@ -67,6 +67,7 @@
      ]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 6cf23a493068a3998d1adeeab26509e2fdb29bca..cefbb8e926bd2464478e819f45c2eac04b426911 100644 (file)
@@ -43,8 +43,9 @@
 -include("jlib.hrl").
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
--include("web/ejabberd_http.hrl").
+-include("ejabberd_http.hrl").
 
 -define(VFIELD(Type, Var, Value),
        #xmlel{name = <<"field">>,
index 352251806fb95b2a758449d68a69e7da779de589..5dde1918695e31e817f1bd75071c5dbbaec9646a 100644 (file)
@@ -29,6 +29,7 @@
 -export([libs/0, config/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("ejabberd_config.hrl").
 
 %% TODO:
index 3b8abf97bbf4c3e78ad0a619a33763f993f20aae..5287876ce06212ab187af94338a0a3a17b88348f 100644 (file)
 
 -include("ejabberd_commands.hrl").
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 
 init() ->
index 269b0a89b783b9470d54d31206d915a05f4a4a2b..fa38847a0ae40e03ccbca69957fdf9444001f9fc 100644 (file)
@@ -38,6 +38,7 @@
 -export([convert_table_to_binary/5]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("ejabberd_config.hrl").
 -include_lib("kernel/include/file.hrl").
 
@@ -447,7 +448,7 @@ process_term(Term, State) ->
        {ejabberdctl_access_commands, ACs} ->
            add_option(ejabberdctl_access_commands, ACs, State);
        {loglevel, Loglevel} ->
-           ejabberd_loglevel:set(Loglevel),
+           ejabberd_logger:set(Loglevel),
            State;
        {max_fsm_queue, N} ->
            add_option(max_fsm_queue, N, State);
index 2b47021761dedda8b7dda1d7792fbfa63a256d58..ba68ee410cbbd637f403cea989a14201630d79e3 100644 (file)
@@ -57,6 +57,7 @@
 -include("ejabberd_ctl.hrl").
 -include("ejabberd_commands.hrl").
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 
 %%-----------------------------
index 98f305536fa59cac191e5df5b1a06b7f1f868b5d..9a33b88e36b11c152833da4e9ad353efb737d4f5 100644 (file)
@@ -206,7 +206,7 @@ handle_call({compress, Data}, _From, State) ->
            State#state.socket, Data),
     Reply = ok,
     {reply, Reply,
-     State#state{socket = ZlibSocket, sockmod = ejabberd_zlib},
+     State#state{socket = ZlibSocket, sockmod = ezlib},
      ?HIBERNATE_TIMEOUT};
 handle_call(reset_stream, _From, State) ->
     ejabberd_receiver:reset_stream(State#state.receiver),
index e4f9f597b806a4a4485013b5e05e5a4e297df3e5..3891fd9ff0e66d3da135d531f3171b9c2aa3cebe 100644 (file)
@@ -55,6 +55,7 @@
         terminate/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %% Timeout of 5 seconds in calls to distributed hooks
 -define(TIMEOUT_DISTRIBUTED_HOOK, 5000).
similarity index 99%
rename from src/web/ejabberd_http.erl
rename to src/ejabberd_http.erl
index 25928c0afc3e7426e611a902951eb205aa823fb3..26e827a71f220259232607fcea6d35e3e89cdae9 100644 (file)
@@ -36,6 +36,7 @@
 -export([init/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/web/ejabberd_http_bind.erl
rename to src/ejabberd_http_bind.erl
index 913291672f4fb3b079493ba3adcae86ecea24cee..976f706ba621192927c6c3c69d8a00457b3be96b 100644 (file)
@@ -41,6 +41,7 @@
         process_request/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/web/ejabberd_http_poll.erl
rename to src/ejabberd_http_poll.erl
index 7648f57106c80ca59d1413bc4bd7168d389358d1..bc974da255217f5cbb517e3981ae4256dfa9c0de 100644 (file)
@@ -37,6 +37,7 @@
         controlling_process/2, close/1, process/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 1f38e88ee5fe23272ee3d3c9f4888970e0dee440..a8ccc186a17a015bd15104e8dde5301080e142fe 100644 (file)
@@ -40,6 +40,7 @@
        ]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %% We do not block on send anymore.
 -define(TCP_SEND_TIMEOUT, 15000).
@@ -549,7 +550,8 @@ format_error(Reason) ->
 
 validate_cfg(L) ->
     lists:map(
-      fun({PortIPTransport, Mod, Opts}) when is_atom(Mod), is_list(Opts) ->
+      fun({PortIPTransport, Mod1, Opts}) when is_atom(Mod1), is_list(Opts) ->
+              Mod = prepare_mod(Mod1),
               case PortIPTransport of
                   Port when ?IS_PORT(Port) ->
                       {Port, Mod, Opts};
@@ -574,3 +576,11 @@ prepare_ip(IP) when is_list(IP) ->
     Addr;
 prepare_ip(IP) when is_binary(IP) ->
     prepare_ip(binary_to_list(IP)).
+
+prepare_mod(ejabberd_stun) ->
+    prepare_mod(stun);
+prepare_mod(stun) ->
+    ejabberd:start_app(p1_stun),
+    stun;
+prepare_mod(Mod) ->
+    Mod.
index 12dfea0c8f43d14912942105a3120b00ac09aebf..f288bed9af3eaaafa11c85876c30174ed5974e8e 100644 (file)
@@ -45,6 +45,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
diff --git a/src/ejabberd_logger.erl b/src/ejabberd_logger.erl
new file mode 100644 (file)
index 0000000..afb1f3f
--- /dev/null
@@ -0,0 +1,70 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2013, Evgeniy Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created : 12 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+-module(ejabberd_logger).
+
+%% API
+-export([start/0, set_logfile/1, reopen_log/0, get/0, set/1,
+         debug_msg/4, info_msg/4, warning_msg/4, error_msg/4,
+         critical_msg/4]).
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+start() ->
+    ok.
+
+set_logfile(FileName) ->
+    error_logger:add_report_handler(p1_logger_h, FileName).
+
+reopen_log() ->
+    %% TODO: Use the Reopen log API for logger_h ?
+    p1_logger_h:reopen_log(),
+    case application:get_env(sasl,sasl_error_logger) of
+       {ok, {file, SASLfile}} ->
+           error_logger:delete_report_handler(sasl_report_file_h),
+           p1_logger_h:rotate_log(SASLfile),
+           error_logger:add_report_handler(sasl_report_file_h,
+               {SASLfile, get_sasl_error_logger_type()});
+       _ -> false
+       end,
+    ok.
+
+get() ->
+    p1_loglevel:get().
+
+set(LogLevel) ->
+    p1_loglevel:set(LogLevel).
+
+debug_msg(Mod, Line, Format, Args) ->
+    p1_logger:debug_msg(Mod, Line, Format, Args).
+
+info_msg(Mod, Line, Format, Args) ->
+    p1_logger:info_msg(Mod, Line, Format, Args).
+
+warning_msg(Mod, Line, Format, Args) ->
+    p1_logger:warning_msg(Mod, Line, Format, Args).
+
+error_msg(Mod, Line, Format, Args) ->
+    p1_logger:error_msg(Mod, Line, Format, Args).
+
+critical_msg(Mod, Line, Format, Args) ->
+    p1_logger:critical_msg(Mod, Line, Format, Args).
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+%% Function copied from Erlang/OTP lib/sasl/src/sasl.erl which doesn't export it
+get_sasl_error_logger_type () ->
+    case application:get_env (sasl, errlog_type) of
+       {ok, error} -> error;
+       {ok, progress} -> progress;
+       {ok, all} -> all;
+       {ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}});
+       _ -> all
+    end.
diff --git a/src/ejabberd_logger_h.erl b/src/ejabberd_logger_h.erl
deleted file mode 100644 (file)
index 6f3e0a6..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : ejabberd_logger_h.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : Manage Erlang logging.
-%%% Created : 23 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(ejabberd_logger_h).
--author('alexey@process-one.net').
-
--behaviour(gen_event).
-
-%% gen_event callbacks
--export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2,
-        code_change/3, reopen_log/0, rotate_log/1]).
-
--record(state, {fd, file}).
-
-%%%----------------------------------------------------------------------
-%%% Callback functions from gen_event
-%%%----------------------------------------------------------------------
-
-%%----------------------------------------------------------------------
-%% Func: init/1
-%% Returns: {ok, State}          |
-%%          Other
-%%----------------------------------------------------------------------
-init(File) ->
-    case file:open(File, [append, raw]) of
-       {ok, Fd} ->
-           {ok, #state{fd = Fd, file = File}};
-       Error ->
-           Error
-    end.
-
-%%----------------------------------------------------------------------
-%% Func: handle_event/2
-%% Returns: {ok, State}                                |
-%%          {swap_handler, Args1, State1, Mod2, Args2} |
-%%          remove_handler                              
-%%----------------------------------------------------------------------
-handle_event(Event, State) ->
-    write_event(State#state.fd, {erlang:localtime(), Event}),
-    {ok, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_call/2
-%% Returns: {ok, Reply, State}                                |
-%%          {swap_handler, Reply, Args1, State1, Mod2, Args2} |
-%%          {remove_handler, Reply}                            
-%%----------------------------------------------------------------------
-handle_call(_Request, State) ->
-    Reply = ok,
-    {ok, Reply, State}.
-
-%%----------------------------------------------------------------------
-%% Func: handle_info/2
-%% Returns: {ok, State}                                |
-%%          {swap_handler, Args1, State1, Mod2, Args2} |
-%%          remove_handler                              
-%%----------------------------------------------------------------------
-handle_info({'EXIT', _Fd, _Reason}, _State) ->
-    remove_handler;
-handle_info({emulator, _GL, reopen}, State) ->
-    file:close(State#state.fd),
-    rotate_log(State#state.file),
-    case file:open(State#state.file, [append, raw]) of
-       {ok, Fd} ->
-           {ok, State#state{fd = Fd}};
-       Error ->
-           Error
-    end;
-handle_info({emulator, GL, Chars}, State) ->
-    write_event(State#state.fd, {erlang:localtime(), {emulator, GL, Chars}}),
-    {ok, State};
-handle_info(_Info, State) ->
-    {ok, State}.
-
-%%----------------------------------------------------------------------
-%% Func: terminate/2
-%% Purpose: Shutdown the server
-%% Returns: any
-%%----------------------------------------------------------------------
-terminate(_Reason, _State) ->
-    ok.
-
-code_change(_OldVsn, State, _Extra) ->
-    {ok, State}.
-
-reopen_log() ->
-    error_logger ! {emulator, noproc, reopen}.
-
-%%%----------------------------------------------------------------------
-%%% Internal functions
-%%%----------------------------------------------------------------------
-
-% Copied from erlang_logger_file_h.erl
-write_event(Fd, {Time, {error, _GL, {Pid, Format, Args}}}) ->
-    T = write_time(Time),
-    case catch io_lib:format(add_node(Format,Pid), Args) of
-       S when is_list(S) ->
-           file:write(Fd, io_lib:format(T ++ S, []));
-       _ ->
-           F = add_node("ERROR: ~p - ~p~n", Pid),
-           file:write(Fd, io_lib:format(T ++ F, [Format,Args]))
-    end;
-write_event(Fd, {Time, {emulator, _GL, Chars}}) ->
-    T = write_time(Time),
-    case catch io_lib:format(Chars, []) of
-       S when is_list(S) ->
-           file:write(Fd, io_lib:format(T ++ S, []));
-       _ ->
-           file:write(Fd, io_lib:format(T ++ "ERROR: ~p ~n", [Chars]))
-    end;
-write_event(Fd, {Time, {info, _GL, {Pid, Info, _}}}) ->
-    T = write_time(Time),
-    file:write(Fd, io_lib:format(T ++ add_node("~p~n",Pid), [Info]));
-write_event(Fd, {Time, {error_report, _GL, {Pid, std_error, Rep}}}) ->
-    T = write_time(Time),
-    S = format_report(Rep),
-    file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), []));
-write_event(Fd, {Time, {info_report, _GL, {Pid, std_info, Rep}}}) ->
-    T = write_time(Time, "INFO REPORT"),
-    S = format_report(Rep),
-    file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), []));
-write_event(Fd, {Time, {info_msg, _GL, {Pid, Format, Args}}}) ->
-    T = write_time(Time, "INFO REPORT"),
-    case catch io_lib:format(add_node(Format,Pid), Args) of
-       S when is_list(S) ->
-           file:write(Fd, io_lib:format(T ++ S, []));
-       _ ->
-           F = add_node("ERROR: ~p - ~p~n", Pid),
-           file:write(Fd, io_lib:format(T ++ F, [Format,Args]))
-    end;
-write_event(Fd, {Time, {warning_report, _GL, {Pid, std_warning, Rep}}}) ->
-    T = write_time(Time, "WARNING REPORT"),
-    S = format_report(Rep),
-    file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), []));
-write_event(Fd, {Time, {warning_msg, _GL, {Pid, Format, Args}}}) ->
-    T = write_time(Time, "WARNING REPORT"),
-    case catch io_lib:format(add_node(Format,Pid), Args) of
-       S when is_list(S) ->
-           file:write(Fd, io_lib:format(T ++ S, []));
-       _ ->
-           F = add_node("ERROR: ~p - ~p~n", Pid),
-           file:write(Fd, io_lib:format(T ++ F, [Format,Args]))
-    end;
-write_event(_, _) ->
-    ok.
-
-format_report(Rep) when is_list(Rep) ->
-    case string_p(Rep) of
-       true ->
-           io_lib:format("~s~n",[Rep]);
-       _ ->
-           format_rep(Rep)
-    end;
-format_report(Rep) ->
-    io_lib:format("~p~n",[Rep]).
-
-format_rep([{Tag,Data}|Rep]) ->
-    io_lib:format("    ~p: ~p~n",[Tag,Data]) ++ format_rep(Rep);
-format_rep([Other|Rep]) ->
-    io_lib:format("    ~p~n",[Other]) ++ format_rep(Rep);
-format_rep(_) ->
-    [].
-
-add_node(X, Pid) when is_atom(X) ->
-    add_node(atom_to_list(X), Pid);
-add_node(X, Pid) when node(Pid) /= node() ->
-    lists:concat([X,"** at node ",node(Pid)," **~n"]);
-add_node(X, _) ->
-    X.
-
-string_p([]) ->
-    false;
-string_p(Term) ->
-    string_p1(Term).
-
-string_p1([H|T]) when is_integer(H), H >= $\s, H < 255 ->
-    string_p1(T);
-string_p1([$\n|T]) -> string_p1(T);
-string_p1([$\r|T]) -> string_p1(T);
-string_p1([$\t|T]) -> string_p1(T);
-string_p1([$\v|T]) -> string_p1(T);
-string_p1([$\b|T]) -> string_p1(T);
-string_p1([$\f|T]) -> string_p1(T);
-string_p1([$\e|T]) -> string_p1(T);
-string_p1([H|T]) when is_list(H) ->
-    case string_p1(H) of
-       true -> string_p1(T);
-       _    -> false
-    end;
-string_p1([]) -> true;
-string_p1(_) ->  false.
-
-write_time(Time) -> write_time(Time, "ERROR REPORT").
-
-write_time({{Y,Mo,D},{H,Mi,S}}, Type) ->
-    io_lib:format("~n=~s==== ~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w ===~n",
-                 [Type, Y, Mo, D, H, Mi, S]).
-
-%% @doc Rename the log file if exists, to "*-old.log".
-%% This is needed in systems when the file must be closed before rotation (Windows).
-%% On most Unix-like system, the file can be renamed from the command line and
-%% the log can directly be reopened.
-%% @spec (Filename::string()) -> ok
-rotate_log(Filename) ->
-    case file:read_file_info(Filename) of
-       {ok, _FileInfo} ->
-           RotationName = filename:rootname(Filename),
-           file:rename(Filename, [RotationName, "-old.log"]),
-           ok;
-       {error, _Reason} ->
-           ok
-    end.
-           
diff --git a/src/ejabberd_loglevel.erl b/src/ejabberd_loglevel.erl
deleted file mode 100644 (file)
index 0306b0b..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : ejabberd_loglevel.erl
-%%% Author  : Mickael Remond <mremond@process-one.net>
-%%% Purpose : Loglevel switcher.
-%%%           Be careful: you should not have any ejabberd_logger module
-%%%           as ejabberd_loglevel switcher is compiling and loading
-%%%           dynamically a "virtual" ejabberd_logger module (Described
-%%%           in a string at the end of this module).
-%%% Created : 29 Nov 2006 by Mickael Remond <mremond@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(ejabberd_loglevel).
--author('mickael.remond@process-one.net').
-
--export([set/1,
-        get/0,
-        set_custom/2,
-        clear_custom/0,
-        clear_custom/1]).
-
--include("ejabberd.hrl").
-
--define(LOGMODULE, "error_logger").
-
-%% Error levels:
--record(loglevel, {ordinal,
-                  name,
-                  description,
-                  function = no_log,
-                  event_type = no_log,
-                  msg_prefix = no_log}).
-
--define(LOG_LEVELS,
-       [#loglevel{ordinal = 0, name = no_log, description = "No log"},
-        #loglevel{ordinal = 1, name = critical, description = "Critical",
-                  function = critical_msg, event_type = error, msg_prefix = "C"},
-        #loglevel{ordinal = 2, name = error, description = "Error",
-                  function = error_msg, event_type = error, msg_prefix = "E"},
-        #loglevel{ordinal = 3, name = warning, description = "Warning",
-                  function = warning_msg, event_type = warning_msg, msg_prefix = "W"},
-        #loglevel{ordinal = 4, name = info, description = "Info",
-                  function = info_msg, event_type = info_msg, msg_prefix = "I"},
-        #loglevel{ordinal = 5, name = debug, description = "Debug",
-                  function = debug_msg, event_type = info_msg, msg_prefix = "D"}]).
-
-%% @type level() = integer() | atom().
-
-%% @spec () -> {DefaultLevelOrdinal::integer(), [{Module::atom(), LevelOrdinal::integer()}]}
-%% @doc Get the default and all custom levels
-get() ->
-    {DefaultLevel, _CustomLevels} = ejabberd_logger:get(),
-    case lists:keysearch(DefaultLevel, #loglevel.ordinal, ?LOG_LEVELS) of
-        {value, Result = #loglevel{}} ->
-           {Result#loglevel.ordinal, Result#loglevel.name, Result#loglevel.description};
-        _ ->
-           erlang:error({no_such_loglevel, DefaultLevel})
-    end.
-
-%% @spec (DefaultLevel::level() | {DefaultLevel::level(), [{Module::atom(), Level::level()}]}) ->
-%%       {module, ejabberd_logger}
-%% @doc Set the default and all custom levels
-set(DefaultLevel) when is_atom(DefaultLevel) orelse is_integer(DefaultLevel) ->
-    set({DefaultLevel, []});
-set({DefaultLevel, CustomLevels}) when is_list(CustomLevels) ->
-    DefaultInt = level_to_integer(DefaultLevel),
-    CustomInts = [level_to_integer(C) || C <- CustomLevels],
-    Loglevel = {DefaultInt, CustomInts},
-    try
-        {Mod,Code} = dynamic_compile:from_string(ejabberd_logger_src(Loglevel)),
-        code:load_binary(Mod, ?LOGMODULE ++ ".erl", Code)
-    catch
-        Type:Error -> ?CRITICAL_MSG("Error compiling logger (~p): ~p~n", [Type, Error])
-    end;
-set(_) ->
-    exit("Invalid loglevel format").
-
-%% @spec (Module::atom(), CustomLevel::level()) -> ok
-%% @doc Set a custom level
-set_custom(Module, Level) ->
-    {DefaultLevel, CustomLevels} = ejabberd_logger:get(),
-    case lists:keysearch(Module, 1, CustomLevels) of
-       {value, {Module, Level}} ->
-           ok;
-       {value, _} ->
-           set({DefaultLevel, lists:keyreplace(Module, 1, CustomLevels, {Module, Level})});
-       _ ->
-           set({DefaultLevel, [{Module, Level} | CustomLevels]})
-    end.
-
-%% @spec () -> ok
-%% @doc Clear all custom levels
-clear_custom() ->
-    {DefaultLevel, _CustomLevels} = ejabberd_logger:get(),
-    set({DefaultLevel, []}).
-
-%% @spec (Module::atom()) -> ok
-%% @doc Clear a custom level
-clear_custom(Module) ->
-    {DefaultLevel, CustomLevels} = ejabberd_logger:get(),
-    case lists:keysearch(Module, 1, CustomLevels) of
-       {value, _} ->
-           set({DefaultLevel, lists:keydelete(Module, 1, CustomLevels)});
-       _ ->
-           ok
-    end.
-
-level_to_integer(Level) when is_integer(Level) ->
-    Level;
-level_to_integer({Module, Level}) ->
-    {Module, level_to_integer(Level)};
-level_to_integer(Level) ->
-    case lists:keysearch(Level, #loglevel.name, ?LOG_LEVELS) of
-        {value, #loglevel{ordinal = Int}} -> Int;
-        _ -> erlang:error({no_such_loglevel, Level})
-    end.
-
-%% --------------------------------------------------------------
-%% Code of the ejabberd logger, dynamically compiled and loaded
-%% This allows to dynamically change log level while keeping a
-%% very efficient code.
-ejabberd_logger_src(Loglevel) ->
-    lists:flatten([header_src(),
-                  get_src(Loglevel),
-                  [log_src(Loglevel, LevelSpec) || LevelSpec <- ?LOG_LEVELS],
-                  notify_src()]).
-
-header_src() ->
-    "-module(ejabberd_logger).
-    -author('mickael.remond@process-one.net').
-
-    -export([debug_msg/4,
-             info_msg/4,
-             warning_msg/4,
-             error_msg/4,
-             critical_msg/4,
-             get/0]).
-    ".
-
-get_src(Loglevel) ->
-    io_lib:format("get() -> ~w.
-                  ", [Loglevel]).
-
-log_src(_Loglevel, #loglevel{function = no_log}) ->
-    [];
-log_src({DefaultLevel, [{Module, Level} | Tail]}, Spec = #loglevel{ordinal = MinLevel})
-  when Level < MinLevel andalso MinLevel =< DefaultLevel ->
-    [atom_to_list(Spec#loglevel.function), "(", atom_to_list(Module), ", _, _, _) -> ok;
-     ", log_src({DefaultLevel, Tail}, Spec)];
-log_src({DefaultLevel, [{Module, Level} | Tail]}, Spec = #loglevel{ordinal = MinLevel})
-  when DefaultLevel < MinLevel andalso MinLevel =< Level ->
-    [atom_to_list(Spec#loglevel.function), "(", atom_to_list(Module), " = Module, Line, Format, Args) ->",
-     log_notify_src(Spec), ";
-     ", log_src({DefaultLevel, Tail}, Spec)];
-log_src({DefaultLevel, [_Head | Tail]}, Spec = #loglevel{}) ->
-    log_src({DefaultLevel, Tail}, Spec);
-log_src({DefaultLevel, []}, Spec = #loglevel{ordinal = MinLevel})
-  when DefaultLevel < MinLevel ->
-    [atom_to_list(Spec#loglevel.function), "(_, _, _, _) -> ok.
-     "];
-log_src({_DefaultLevel, []}, Spec = #loglevel{}) ->
-    [atom_to_list(Spec#loglevel.function), "(Module, Line, Format, Args) ->",
-     log_notify_src(Spec), ".
-     "].
-
-log_notify_src(Spec = #loglevel{}) ->
-    ["notify(", atom_to_list(Spec#loglevel.event_type), ",
-        \"", Spec#loglevel.msg_prefix, "(~p:~p:~p) : \"++Format++\"~n\",
-        [self(), Module, Line | Args])"].
-
-notify_src() ->
-    %% Distribute the message to the Erlang error logger
-    "notify(Type, Format, Args) ->
-            LoggerMsg = {Type, group_leader(), {self(), Format, Args}},
-            gen_event:notify(error_logger, LoggerMsg).
-    ".
similarity index 99%
rename from src/odbc/ejabberd_odbc.erl
rename to src/ejabberd_odbc.erl
index 1cb157c0589081a631e0619b6b7ea0cfb4b55d97..b530f8f29c7a8fe9433ce1ce81dda9dce0bded49 100644 (file)
@@ -55,6 +55,7 @@
         session_established/2, session_established/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -record(state,
        {db_ref = self()                     :: pid(),
@@ -482,7 +483,7 @@ abort_on_driver_error(Reply, From) ->
 %% part of init/1
 %% Open an ODBC database connection
 odbc_connect(SQLServer) ->
-    application:start(odbc),
+    ejabberd:start_app(odbc),
     odbc:connect(SQLServer, [{scrollable_cursors, off}]).
 
 %% == Native PostgreSQL code
similarity index 99%
rename from src/odbc/ejabberd_odbc_sup.erl
rename to src/ejabberd_odbc_sup.erl
index 0c748d1471c93a368f9b5b93ac85d0f05f15657d..2ddc751f8f48f70782e63d71f0a2eef268d78491 100644 (file)
@@ -33,6 +33,7 @@
         get_pids/1, get_random_pid/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -define(DEFAULT_POOL_SIZE, 10).
 
index 668f1ba62d155b7c3d9539c6fb845ab3c1c00759..6c13e7426fd06346433302c6bdf8dd933a4af876 100644 (file)
@@ -45,6 +45,7 @@
 -define(CHUNK_SIZE, 1024*20). %20k
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 -include("mod_privacy.hrl").
 -include("mod_roster.hrl").
index abb17974cf4f4e7b7030c8fda6abbf14bbd6314d..b35786cdec77d6841d6e93b8a190042bc2edfce1 100644 (file)
 -export([start/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 start() ->
-    case catch ejabberd_odbc_sup:module_info() of
-      {'EXIT', {undef, _}} ->
-         ?INFO_MSG("ejabberd has not been compiled with "
-                   "relational database support. Skipping "
-                   "database startup.",
-                   []);
-      _ -> start_hosts()
+    case lists:any(fun needs_odbc/1, ?MYHOSTS) of
+        true ->
+            start_hosts();
+        false ->
+            ok
     end.
 
 %% Start relationnal DB module on the nodes where it is needed
index c9ed6b35074078dfab129cfe156ada8748d5409c..43e6595f915ea38ae94e9bee1260d4843f447810 100644 (file)
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -record(state,
-       {socket :: inet:socket() | tls:tls_socket() | ejabberd_zlib:zlib_socket(),
-         sock_mod = gen_tcp :: gen_tcp | tls | ejabberd_zlib,
+       {socket :: inet:socket() | tls:tls_socket() | ezlib:zlib_socket(),
+         sock_mod = gen_tcp :: gen_tcp | tls | ezlib,
          shaper_state = none :: shaper:shaper(),
          c2s_pid :: pid(),
         max_stanza_size = infinity :: non_neg_integer() | infinity,
@@ -107,10 +108,10 @@ starttls(Pid, TLSSocket) ->
     do_call(Pid, {starttls, TLSSocket}).
 
 -spec compress(pid(), iodata() | undefined) -> {error, any()} |
-                                               {ok, ejabberd_zlib:zlib_socket()}.
+                                               {ok, ezlib:zlib_socket()}.
 
-compress(Pid, ZlibSocket) ->
-    do_call(Pid, {compress, ZlibSocket}).
+compress(Pid, Data) ->
+    do_call(Pid, {compress, Data}).
 
 -spec become_controller(pid(), pid()) -> ok | {error, any()}.
 
@@ -170,21 +171,27 @@ handle_call({starttls, TLSSocket}, _From,
        {error, _Reason} ->
            {stop, normal, ok, NewState}
     end;
-handle_call({compress, ZlibSocket}, _From,
+handle_call({compress, Data}, _From,
            #state{xml_stream_state = XMLStreamState,
-                  c2s_pid = C2SPid,
-                  max_stanza_size = MaxStanzaSize} = State) ->
+                  c2s_pid = C2SPid, socket = Socket, sock_mod = SockMod,
+                  max_stanza_size = MaxStanzaSize} =
+               State) ->
+    {ok, ZlibSocket} = ezlib:enable_zlib(SockMod,
+                                                Socket),
+    if Data /= undefined -> do_send(State, Data);
+       true -> ok
+    end,
     close_stream(XMLStreamState),
     NewXMLStreamState = xml_stream:new(C2SPid,
                                       MaxStanzaSize),
     NewState = State#state{socket = ZlibSocket,
-                          sock_mod = ejabberd_zlib,
+                          sock_mod = ezlib,
                           xml_stream_state = NewXMLStreamState},
-    case ejabberd_zlib:recv_data(ZlibSocket, <<"">>) of
-       {ok, ZlibData} ->
-           {reply, ok, process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT};
-       {error, _Reason} ->
-           {stop, normal, ok, NewState}
+    case ezlib:recv_data(ZlibSocket, <<"">>) of
+      {ok, ZlibData} ->
+         {reply, {ok, ZlibSocket},
+          process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT};
+      {error, _Reason} -> {stop, normal, ok, NewState}
     end;
 handle_call(reset_stream, _From,
            #state{xml_stream_state = XMLStreamState,
@@ -239,8 +246,8 @@ handle_info({Tag, _TCPSocket, Data},
                 ?HIBERNATE_TIMEOUT};
            {error, _Reason} -> {stop, normal, State}
          end;
-      ejabberd_zlib ->
-         case ejabberd_zlib:recv_data(Socket, Data) of
+      ezlib ->
+         case ezlib:recv_data(Socket, Data) of
            {ok, ZlibData} ->
                {noreply, process_data(ZlibData, State),
                 ?HIBERNATE_TIMEOUT};
@@ -361,6 +368,9 @@ close_stream(undefined) -> ok;
 close_stream(XMLStreamState) ->
     xml_stream:close(XMLStreamState).
 
+do_send(State, Data) ->
+    (State#state.sock_mod):send(State#state.socket, Data).
+
 do_call(Pid, Msg) ->
     case catch gen_server:call(Pid, Msg) of
       {'EXIT', Why} -> {error, Why};
index 47a25fdd9f9113a1c4a05f49bfa7d6a92aab7fee..ea020a186fc69dc55572bf28b3569c86e9bfbecd 100644 (file)
@@ -49,6 +49,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 0832d1dfd45e2635b5e3b5412b0b2899110ee956..63fdc766052201d5c3dfbdd61e7138d99f77deed 100644 (file)
@@ -48,6 +48,7 @@
 -export([get_info_s2s_connections/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 2dc7c86b2c4806e8bfa6888de302ea383cc39f13..3b1a24180eb7f4631745987d5ccfa9475490fc52 100644 (file)
@@ -41,6 +41,7 @@
         handle_info/3, print_state/1, terminate/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 4bfb0e732fdfe4b1336828855b8ff6fff43e2cc1..9829b621dd709775b70f85dea93c79bedc5871d0 100644 (file)
@@ -59,6 +59,7 @@
         get_addr_port/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 5a80fcd906b5d8c8c5111ab17aab4ac7d29d17e5..960d61420179482f0b26ae178ee25606c4203a29 100644 (file)
@@ -43,6 +43,7 @@
         handle_info/3, terminate/3, print_state/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 4ab5975fa314171b7024d6ac0da32370a545bc73..755c2e92efba6cfbd0c2944018399901f89aabf2 100644 (file)
@@ -63,6 +63,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index d06c489529b9848c3c2eee19c41e3aca59614c00..31d612d7d13073462d16d432fe24627e2512969b 100644 (file)
@@ -48,6 +48,7 @@
         sockname/1, peername/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 
 -type sockmod() :: ejabberd_http_poll |
@@ -56,7 +57,7 @@
 -type receiver() :: pid () | atom().
 -type socket() :: pid() | inet:socket() |
                   tls:tls_socket() |
-                  ejabberd_zlib:zlib_socket() |
+                  ezlib:zlib_socket() |
                   ejabberd_http_bind:bind_socket() |
                   ejabberd_http_poll:poll_socket().
 
@@ -167,12 +168,11 @@ compress(SocketData) ->
     SocketData#socket_state{socket = ZlibSocket, sockmod = ejabberd_zlib}.
 
 compress(SocketData, Data) ->
-    {ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
-                        SocketData#socket_state.sockmod,
-                        SocketData#socket_state.socket),
-    ejabberd_receiver:compress(SocketData#socket_state.receiver, ZlibSocket),
-    send(SocketData, Data),
-    SocketData#socket_state{socket = ZlibSocket, sockmod = ejabberd_zlib}.
+    {ok, ZlibSocket} =
+       ejabberd_receiver:compress(SocketData#socket_state.receiver,
+                                  Data),
+    SocketData#socket_state{socket = ZlibSocket,
+                           sockmod = ezlib}.
 
 reset_stream(SocketData)
     when is_pid(SocketData#socket_state.receiver) ->
index 7dcd2923296dbb697cd2c6cb03d77ec34e600c98..b3da8369db72470bfb91f2520ed2e285cd6c8536 100644 (file)
@@ -169,21 +169,6 @@ init([]) ->
         infinity,
         supervisor,
         [ejabberd_tmp_sup]},
-    STUNSupervisor =
-       {ejabberd_stun_sup,
-        {ejabberd_tmp_sup, start_link,
-         [ejabberd_stun_sup, ejabberd_stun]},
-        permanent,
-        infinity,
-        supervisor,
-        [ejabberd_tmp_sup]},
-    CacheTabSupervisor =
-       {cache_tab_sup,
-        {cache_tab_sup, start_link, []},
-        permanent,
-        infinity,
-        supervisor,
-        [cache_tab_sup]},
     {ok, {{one_for_one, 10, 1},
          [Hooks,
           NodeGroups,
@@ -201,9 +186,7 @@ init([]) ->
           HTTPSupervisor,
           HTTPPollSupervisor,
           IQSupervisor,
-          STUNSupervisor,
           FrontendSocketSupervisor,
-          CacheTabSupervisor,
           Listener]}}.
 
 
index 1273226c4f4105ba9d6abd71c56a2cb31facdb63..2f5d1c3307632957869adb4a13ad1b3dd93f8402 100644 (file)
@@ -39,6 +39,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 6a7f8bc9a9e0b0be62002972d7125501911a3209..41c2ea510c474dda42fe3ce72f44bf30ec4f44f1 100644 (file)
@@ -31,6 +31,7 @@
 -export([update/0, update/1, update_info/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %%====================================================================
 %% API
similarity index 99%
rename from src/web/ejabberd_web.erl
rename to src/ejabberd_web.erl
index 8c7ccaf69dba537a69afb5fb477ef64e71a49be1..70f62de7fbcc92b66c3a7c774f91cddae858bb91 100644 (file)
@@ -33,6 +33,7 @@
 -export([make_xhtml/1, make_xhtml/2, error/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/web/ejabberd_web_admin.erl
rename to src/ejabberd_web_admin.erl
index 73c7ab52a8afac5d08bc60acf2059ad9bb87c612..de9142c185c65139250033ef7c988ba377df8954 100644 (file)
@@ -36,6 +36,7 @@
         term_to_id/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
diff --git a/src/ejabberd_zlib/Makefile.in b/src/ejabberd_zlib/Makefile.in
deleted file mode 100644 (file)
index b572c11..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ZLIB_CFLAGS = @ZLIB_CFLAGS@
-ZLIB_LIBS = @ZLIB_LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-ifeq ($(shell uname),Darwin)
-    DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-endif
-ifeq ($(shell uname),SunOs)
-    DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
-endif
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-ERLSHLIBS = ../ejabberd_zlib_drv.so
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-all:    $(BEAMS) $(ERLSHLIBS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-#all:  $(ERLSHLIBS)
-#      erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
-
-$(ERLSHLIBS):  ../%.so:        %.c
-       $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
-               $(subst ../,,$(subst .so,.c,$@)) \
-               $(LIBS) \
-               $(ZLIB_LIBS) \
-               $(ZLIB_CFLAGS) \
-               $(ERLANG_LIBS) \
-               $(ERLANG_CFLAGS) \
-               -o $@ \
-               $(DYNAMIC_LIB_CFLAGS)
-
-clean:
-       rm -f $(BEAMS) $(ERLSHLIBS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
diff --git a/src/ejabberd_zlib/Makefile.win32 b/src/ejabberd_zlib/Makefile.win32
deleted file mode 100644 (file)
index 0041df8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\ejabberd_zlib.beam
-
-SOURCE = ejabberd_zlib_drv.c
-OBJECT = ejabberd_zlib_drv.o
-DLL    = $(OUTDIR)\ejabberd_zlib_drv.dll
-
-ALL : $(DLL) $(BEAMS)
-
-CLEAN :
-       -@erase $(DLL)
-       -@erase $(OUTDIR)\ejabberd_zlib_drv.exp
-       -@erase $(OUTDIR)\ejabberd_zlib_drv.lib
-       -@erase $(OBJECT)
-       -@erase $(BEAMS)
-
-$(OUTDIR)\ejabberd_zlib.beam : ejabberd_zlib.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_zlib.erl
-
-CC=cl.exe
-CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(ZLIB_DIR)\include"
-
-LD=link.exe
-LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(ZLIB_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
-
-$(DLL) : $(OBJECT)
-       $(LD) $(LD_FLAGS) -out:$@ $<
-
-$(OBJECT) : $(SOURCE)
-       $(CC) $(CC_FLAGS) -c -Fo$@ $<
-
diff --git a/src/ejabberd_zlib/ejabberd_zlib.erl b/src/ejabberd_zlib/ejabberd_zlib.erl
deleted file mode 100644 (file)
index 3dee8d6..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : ejabberd_zlib.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : Interface to zlib
-%%% Created : 19 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(ejabberd_zlib).
-
--author('alexey@process-one.net').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0, enable_zlib/2,
-        disable_zlib/1, send/2, recv/2, recv/3, recv_data/2,
-        setopts/2, sockname/1, peername/1, get_sockmod/1,
-        controlling_process/2, close/1]).
-
-%% Internal exports, call-back functions.
--export([init/1, handle_call/3, handle_cast/2,
-        handle_info/2, code_change/3, terminate/2]).
-
--define(DEFLATE, 1).
-
--define(INFLATE, 2).
-
--record(zlibsock, {sockmod :: atom(),
-                   socket :: inet:socket(),
-                   zlibport :: port()}).
-
--type zlib_socket() :: #zlibsock{}.
-
--export_type([zlib_socket/0]).
-
-start() ->
-    gen_server:start({local, ?MODULE}, ?MODULE, [], []).
-
-start_link() ->
-    gen_server:start_link({local, ?MODULE}, ?MODULE, [],
-                         []).
-
-init([]) ->
-    case erl_ddll:load_driver(ejabberd:get_so_path(),
-                             ejabberd_zlib_drv)
-       of
-      ok -> ok;
-      {error, already_loaded} -> ok
-    end,
-    Port = open_port({spawn, "ejabberd_zlib_drv"},
-                    [binary]),
-    {ok, Port}.
-
-%%% --------------------------------------------------------
-%%% The call-back functions.
-%%% --------------------------------------------------------
-
-handle_call(_, _, State) -> {noreply, State}.
-
-handle_cast(_, State) -> {noreply, State}.
-
-handle_info({'EXIT', Port, Reason}, Port) ->
-    {stop, {port_died, Reason}, Port};
-handle_info({'EXIT', _Pid, _Reason}, Port) ->
-    {noreply, Port};
-handle_info(_, State) -> {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
-
-terminate(_Reason, Port) -> Port ! {self, close}, ok.
-
--spec enable_zlib(atom(), inet:socket()) -> {ok, zlib_socket()}.
-
-enable_zlib(SockMod, Socket) ->
-    case erl_ddll:load_driver(ejabberd:get_so_path(),
-                             ejabberd_zlib_drv)
-       of
-      ok -> ok;
-      {error, already_loaded} -> ok
-    end,
-    Port = open_port({spawn, "ejabberd_zlib_drv"},
-                    [binary]),
-    {ok,
-     #zlibsock{sockmod = SockMod, socket = Socket,
-              zlibport = Port}}.
-
--spec disable_zlib(zlib_socket()) -> {atom(), inet:socket()}.
-
-disable_zlib(#zlibsock{sockmod = SockMod,
-                      socket = Socket, zlibport = Port}) ->
-    port_close(Port), {SockMod, Socket}.
-
--spec recv(zlib_socket(), number()) -> {ok, binary()} | {error, any()}.
-
-recv(Socket, Length) -> recv(Socket, Length, infinity).
-
--spec recv(zlib_socket(), number(), timeout()) -> {ok, binary()} |
-                                                  {error, any()}.
-
-recv(#zlibsock{sockmod = SockMod, socket = Socket} =
-        ZlibSock,
-     Length, Timeout) ->
-    case SockMod:recv(Socket, Length, Timeout) of
-      {ok, Packet} -> recv_data(ZlibSock, Packet);
-      {error, _Reason} = Error -> Error
-    end.
-
--spec recv_data(zlib_socket(), iodata()) -> {ok, binary()} | {error, any()}.
-
-recv_data(#zlibsock{sockmod = SockMod,
-                   socket = Socket} =
-             ZlibSock,
-         Packet) ->
-    case SockMod of
-      gen_tcp -> recv_data2(ZlibSock, Packet);
-      _ ->
-         case SockMod:recv_data(Socket, Packet) of
-           {ok, Packet2} -> recv_data2(ZlibSock, Packet2);
-           Error -> Error
-         end
-    end.
-
-recv_data2(ZlibSock, Packet) ->
-    case catch recv_data1(ZlibSock, Packet) of
-      {'EXIT', Reason} -> {error, Reason};
-      Res -> Res
-    end.
-
-recv_data1(#zlibsock{zlibport = Port} = _ZlibSock,
-          Packet) ->
-    case port_control(Port, ?INFLATE, Packet) of
-      <<0, In/binary>> -> {ok, In};
-      <<1, Error/binary>> -> {error, (Error)}
-    end.
-
--spec send(zlib_socket(), iodata()) -> ok | {error, binary() | inet:posix()}.
-
-send(#zlibsock{sockmod = SockMod, socket = Socket,
-              zlibport = Port},
-     Packet) ->
-    case port_control(Port, ?DEFLATE, Packet) of
-      <<0, Out/binary>> -> SockMod:send(Socket, Out);
-      <<1, Error/binary>> -> {error, (Error)}
-    end.
-
--spec setopts(zlib_socket(), list()) -> ok | {error, inet:posix()}.
-
-setopts(#zlibsock{sockmod = SockMod, socket = Socket},
-       Opts) ->
-    case SockMod of
-      gen_tcp -> inet:setopts(Socket, Opts);
-      _ -> SockMod:setopts(Socket, Opts)
-    end.
-
--spec sockname(zlib_socket()) -> {ok, {inet:ip_address(), inet:port_number()}} |
-                                 {error, inet:posix()}.
-
-sockname(#zlibsock{sockmod = SockMod,
-                  socket = Socket}) ->
-    case SockMod of
-      gen_tcp -> inet:sockname(Socket);
-      _ -> SockMod:sockname(Socket)
-    end.
-
--spec get_sockmod(zlib_socket()) -> atom().
-
-get_sockmod(#zlibsock{sockmod = SockMod}) -> SockMod.
-
--spec peername(zlib_socket()) -> {ok, {inet:ip_address(), inet:port_number()}} |
-                                 {error, inet:posix()}.
-
-peername(#zlibsock{sockmod = SockMod,
-                  socket = Socket}) ->
-    case SockMod of
-      gen_tcp -> inet:peername(Socket);
-      _ -> SockMod:peername(Socket)
-    end.
-
--spec controlling_process(zlib_socket(), pid()) -> ok | {error, atom()}.
-
-controlling_process(#zlibsock{sockmod = SockMod,
-                             socket = Socket},
-                   Pid) ->
-    SockMod:controlling_process(Socket, Pid).
-
--spec close(zlib_socket()) -> true.
-
-close(#zlibsock{sockmod = SockMod, socket = Socket,
-               zlibport = Port}) ->
-    SockMod:close(Socket), port_close(Port).
diff --git a/src/ejabberd_zlib/ejabberd_zlib_drv.c b/src/ejabberd_zlib/ejabberd_zlib_drv.c
deleted file mode 100644 (file)
index ea1cc74..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013   ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <zlib.h>
-
-/*
- * R15B changed several driver callbacks to use ErlDrvSizeT and
- * ErlDrvSSizeT typedefs instead of int.
- * This provides missing typedefs on older OTP versions.
- */
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int ErlDrvSizeT;
-typedef int ErlDrvSSizeT;
-#endif
-
-#define BUF_SIZE 1024
-
-typedef struct {
-      ErlDrvPort port;
-      z_stream *d_stream;
-      z_stream *i_stream;
-} ejabberd_zlib_data;
-
-static void* zlib_alloc(void* data, unsigned int items, unsigned int size)
-{
-    return (void*) driver_alloc(items*size);
-}
-
-static void zlib_free(void* data, void* addr)
-{
-    driver_free(addr);
-}
-
-static ErlDrvData ejabberd_zlib_drv_start(ErlDrvPort port, char *buff)
-{
-   ejabberd_zlib_data *d =
-      (ejabberd_zlib_data *)driver_alloc(sizeof(ejabberd_zlib_data));
-   d->port = port;
-
-   d->d_stream = (z_stream *)driver_alloc(sizeof(z_stream));
-
-   d->d_stream->zalloc = zlib_alloc;
-   d->d_stream->zfree = zlib_free;
-   d->d_stream->opaque = (voidpf)0;
-
-   deflateInit(d->d_stream, Z_DEFAULT_COMPRESSION);
-
-   d->i_stream = (z_stream *)driver_alloc(sizeof(z_stream));
-
-   d->i_stream->zalloc = zlib_alloc;
-   d->i_stream->zfree = zlib_free;
-   d->i_stream->opaque = (voidpf)0;
-
-   inflateInit(d->i_stream);
-
-   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
-   return (ErlDrvData)d;
-}
-
-static void ejabberd_zlib_drv_stop(ErlDrvData handle)
-{
-   ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle;
-
-   deflateEnd(d->d_stream);
-   driver_free(d->d_stream);
-
-   inflateEnd(d->i_stream);
-   driver_free(d->i_stream);
-
-   driver_free((char *)handle);
-}
-
-
-#define DEFLATE 1
-#define INFLATE 2
-
-#define die_unless(cond, errstr)                               \
-        if (!(cond))                                           \
-        {                                                      \
-           rlen = strlen(errstr) + 1;                          \
-           b = driver_realloc_binary(b, rlen);                 \
-           b->orig_bytes[0] = 1;                               \
-           strncpy(b->orig_bytes + 1, errstr, rlen - 1);       \
-           *rbuf = (char *)b;                                  \
-           return rlen;                                        \
-        }
-
-
-static ErlDrvSSizeT ejabberd_zlib_drv_control(ErlDrvData handle,
-                                    unsigned int command,
-                                    char *buf, ErlDrvSizeT len,
-                                    char **rbuf, ErlDrvSizeT rlen)
-{
-   ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle;
-   int err;
-   int size;
-   ErlDrvBinary *b;
-
-   switch (command)
-   {
-      case DEFLATE:
-        size = BUF_SIZE + 1;
-        rlen = 1;
-        b = driver_alloc_binary(size);
-        b->orig_bytes[0] = 0;
-
-        d->d_stream->next_in = (unsigned char *)buf;
-        d->d_stream->avail_in = len;
-        d->d_stream->avail_out = 0;
-        err = Z_OK;
-
-        while (err == Z_OK && d->d_stream->avail_out == 0)
-        {
-           d->d_stream->next_out = (unsigned char *)b->orig_bytes + rlen;
-           d->d_stream->avail_out = BUF_SIZE;
-
-           err = deflate(d->d_stream, Z_SYNC_FLUSH);
-           die_unless((err == Z_OK) || (err == Z_STREAM_END),
-                      "Deflate error");
-
-           rlen += (BUF_SIZE - d->d_stream->avail_out);
-           size += (BUF_SIZE - d->d_stream->avail_out);
-           b = driver_realloc_binary(b, size);
-        }
-        b = driver_realloc_binary(b, rlen);
-        *rbuf = (char *)b;
-        return rlen;
-      case INFLATE:
-        size = BUF_SIZE + 1;
-        rlen = 1;
-        b = driver_alloc_binary(size);
-        b->orig_bytes[0] = 0;
-
-        if (len > 0) {
-           d->i_stream->next_in = (unsigned char *)buf;
-           d->i_stream->avail_in = len;
-           d->i_stream->avail_out = 0;
-           err = Z_OK;
-
-           while (err == Z_OK && d->i_stream->avail_out == 0)
-           {
-              d->i_stream->next_out = (unsigned char *)b->orig_bytes + rlen;
-              d->i_stream->avail_out = BUF_SIZE;
-
-              err = inflate(d->i_stream, Z_SYNC_FLUSH);
-              die_unless((err == Z_OK) || (err == Z_STREAM_END),
-                         "Inflate error");
-
-              rlen += (BUF_SIZE - d->i_stream->avail_out);
-              size += (BUF_SIZE - d->i_stream->avail_out);
-              b = driver_realloc_binary(b, size);
-           }
-        }
-        b = driver_realloc_binary(b, rlen);
-        *rbuf = (char *)b;
-        return rlen;
-   }
-
-   b = driver_alloc_binary(1);
-   b->orig_bytes[0] = 0;
-   *rbuf = (char *)b;
-   return 1;
-}
-
-
-ErlDrvEntry ejabberd_zlib_driver_entry = {
-   NULL,                       /* F_PTR init, N/A */
-   ejabberd_zlib_drv_start,    /* L_PTR start, called when port is opened */
-   ejabberd_zlib_drv_stop,     /* F_PTR stop, called when port is closed */
-   NULL,                       /* F_PTR output, called when erlang has sent */
-   NULL,                       /* F_PTR ready_input, called when input descriptor ready */
-   NULL,                       /* F_PTR ready_output, called when output descriptor ready */
-   "ejabberd_zlib_drv",                /* char *driver_name, the argument to open_port */
-   NULL,                       /* F_PTR finish, called when unloaded */
-   NULL,                       /* handle */
-   ejabberd_zlib_drv_control,   /* F_PTR control, port_command callback */
-   NULL,                       /* F_PTR timeout, reserved */
-   NULL,                       /* F_PTR outputv, reserved */
-  /* Added in Erlang/OTP R15B: */
-  NULL,                 /* ready_async */
-  NULL,                 /* flush */
-  NULL,                 /* call */
-  NULL,                 /* event */
-  ERL_DRV_EXTENDED_MARKER,        /* extended_marker */
-  ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */
-  ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */
-  0,                    /* driver_flags */
-  NULL,                 /* handle2 */
-  NULL,                 /* process_exit */
-  NULL                  /* stop_select */
-};
-
-DRIVER_INIT(ejabberd_zlib_drv) /* must match name in driver_entry */
-{
-   return &ejabberd_zlib_driver_entry;
-}
-
-
similarity index 99%
rename from src/eldap/eldap.erl
rename to src/eldap.erl
index 4df7d00eb375c9cbf96553757799f6ba5c426cea..0dae3cbe883b86923847c02dbc00f044cd13d9ff 100644 (file)
@@ -66,6 +66,7 @@
 -behaviour(gen_fsm).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %% External exports
 -export([start_link/1, start_link/6]).
@@ -567,7 +568,6 @@ get_handle(Name) when is_binary(Name) ->
 %% process.      
 %%----------------------------------------------------------------------
 init([Hosts, Port, Rootdn, Passwd, Opts]) ->
-    catch ssl:start(),
     Encrypt = case gen_mod:get_opt(encrypt, Opts,
                                    fun(tls) -> tls;
                                       (starttls) -> starttls;
diff --git a/src/eldap/Makefile.in b/src/eldap/Makefile.in
deleted file mode 100644 (file)
index 6d895ee..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-# $Id: Makefile.in 2842 2009-12-29 19:10:52Z badlop $
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ASN_FLAGS = -bber_bin +optimize +binary_strings
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl) ELDAPv3.erl eldap_filter_yecc.erl
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS) ELDAPv3.beam eldap_filter_yecc.beam
-
-ELDAPv3.beam: ELDAPv3.erl
-
-ELDAPv3.erl:       ELDAPv3.asn
-       @ERLC@ $(ASN_FLAGS) -W $(EFLAGS) $<
-       @ERL@ -noinput +B -eval \
-       'case file:read_file("ELDAPv3.erl") of {ok, Data} -> NewData = re:replace(Data, "\\?RT_BER:decode_octet_string", "eldap_utils:decode_octet_string", [global]), file:write_file("ELDAPv3.erl", NewData), halt(0); _Err -> halt(1) end'
-
-eldap_filter_yecc.beam: eldap_filter_yecc.erl
-
-eldap_filter_yecc.erl: eldap_filter_yecc.yrl
-       @ERLC@ -W $<
-
-$(OUTDIR)/%.beam:      %.erl ELDAPv3.erl eldap_filter_yecc.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f ELDAPv3.asn1db
-       rm -f ELDAPv3.erl
-       rm -f ELDAPv3.hrl
-       rm -f ELDAPv3.beam
-       rm -f eldap_filter_yecc.erl
-       rm -f eldap_filter_yecc.beam
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/eldap/Makefile.win32 b/src/eldap/Makefile.win32
deleted file mode 100644 (file)
index 394055d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\eldap.beam ..\eldap_filter.beam ..\eldap_pool.beam ..\eldap_utils.beam ..\eldap_filter_yecc.beam
-
-ASN_FLAGS = -bber_bin +optimize
-
-ALL : $(BEAMS)
-
-Clean :
-       -@erase ELDAPv3.asn1db
-       -@erase ELDAPv3.erl
-       -@erase ELDAPv3.hrl
-       -@erase ELDAPv3.beam
-       -@erase eldap_filter_yecc.erl
-       -@erase eldap_filter_yecc.beam
-       -@erase $(BEAMS)
-
-ELDAPv3.erl : ELDAPv3.asn
-       erlc $(ASN_FLAGS) -W $(EFLAGS) ELDAPv3.asn
-
-eldap_filter_yecc.erl: eldap_filter_yecc.yrl
-       erlc -W eldap_filter_yecc.yrl
-
-$(OUTDIR)\eldap.beam : eldap.erl ELDAPv3.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) eldap.erl
-
-$(OUTDIR)\ELDAPv3.beam : ELDAPv3.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ELDAPv3.erl
-
-$(OUTDIR)\eldap_filter.beam : eldap_filter.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) eldap_filter.erl
-
-$(OUTDIR)\eldap_utils.beam : eldap_utils.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) eldap_utils.erl
-
-$(OUTDIR)\eldap_pool.beam : eldap_pool.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) eldap_pool.erl
-
-$(OUTDIR)\eldap_filter_yecc.beam : eldap_filter_yecc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) eldap_filter_yecc.erl
similarity index 99%
rename from src/eldap/eldap_pool.erl
rename to src/eldap_pool.erl
index 1f52999ef50dbf4f1ae71d33045dfaa9ca318045..35fabeb7451d75c48e68e3fdf72ef36f2e3eed98 100644 (file)
@@ -33,6 +33,7 @@
         modify_passwd/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %%====================================================================
 %% API
similarity index 99%
rename from src/eldap/eldap_utils.erl
rename to src/eldap_utils.erl
index 2e149d8b601547dcc5d3c1f6c3596d6d8d4e42a8..6209802a811bbab93f39ab42127e4ac020a217f4 100644 (file)
@@ -41,6 +41,7 @@
         uids_domain_subst/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("eldap.hrl").
 
 %% Generate an 'or' LDAP query on one or several attributes
diff --git a/src/expat_erl.c b/src/expat_erl.c
deleted file mode 100644 (file)
index 02d41ed..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013   ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <ei.h>
-#include <expat.h>
-
-
-#define XML_START 0
-#define XML_END   1
-#define XML_CDATA 2
-#define XML_ERROR 3
-
-#define PARSE_COMMAND 0
-#define PARSE_FINAL_COMMAND 1
-
-/*
- * R15B changed several driver callbacks to use ErlDrvSizeT and
- * ErlDrvSSizeT typedefs instead of int.
- * This provides missing typedefs on older OTP versions.
- */
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int ErlDrvSizeT;
-typedef int ErlDrvSSizeT;
-#endif
-
-ei_x_buff event_buf;
-ei_x_buff xmlns_buf;
-
-typedef struct {
-      ErlDrvPort port;
-      XML_Parser parser;
-} expat_data;
-
-static XML_Memory_Handling_Suite ms;
-
-void encode_name(const XML_Char *name)
-{
-  char *name_start;
-  char *prefix_start;
-  char *buf;
-  int name_len, prefix_len, buf_len;
-
-  if ((name_start = strchr(name, '\n'))) {
-    if ((prefix_start = strchr(name_start+1, '\n'))) {
-      name_len = prefix_start - name_start;
-      prefix_len = strlen(prefix_start+1);
-      buf_len = prefix_len + name_len;
-      buf = driver_alloc(buf_len);
-      memcpy(buf, prefix_start+1, prefix_len);
-      memcpy(buf+prefix_len, name_start, name_len);
-      buf[prefix_len] = ':';
-      ei_x_encode_binary(&event_buf, buf, buf_len);
-      driver_free(buf);
-    } else {
-       ei_x_encode_binary(&event_buf, name_start+1, strlen(name_start+1));
-    };
-  } else {
-     ei_x_encode_binary(&event_buf, name, strlen(name));
-  }
-}
-
-void *erlXML_StartElementHandler(expat_data *d,
-                                const XML_Char *name,
-                                const XML_Char **atts)
-{
-   int i;
-
-   ei_x_encode_list_header(&event_buf, 1);
-   ei_x_encode_tuple_header(&event_buf, 2);
-   ei_x_encode_long(&event_buf, XML_START);
-   ei_x_encode_tuple_header(&event_buf, 2);
-   encode_name(name);
-   ei_x_append(&event_buf, &xmlns_buf);
-   ei_x_free(&xmlns_buf);
-   ei_x_new(&xmlns_buf);
-
-   for (i = 0; atts[i]; i += 2) {}
-
-   if (i > 0)
-   {
-      ei_x_encode_list_header(&event_buf, i/2);
-
-      for (i = 0; atts[i]; i += 2)
-      {
-        ei_x_encode_tuple_header(&event_buf, 2);
-        encode_name(atts[i]);
-        ei_x_encode_binary(&event_buf, atts[i+1], strlen(atts[i+1]));
-      }
-   }
-
-   ei_x_encode_empty_list(&event_buf);
-
-   return NULL;
-}
-
-void *erlXML_EndElementHandler(expat_data *d,
-                              const XML_Char *name)
-{
-   ei_x_encode_list_header(&event_buf, 1);
-   ei_x_encode_tuple_header(&event_buf, 2);
-   ei_x_encode_long(&event_buf, XML_END);
-   encode_name(name);
-   return NULL;
-}
-
-void *erlXML_CharacterDataHandler(expat_data *d,
-                                 const XML_Char *s,
-                                 int len)
-{
-   ei_x_encode_list_header(&event_buf, 1);
-   ei_x_encode_tuple_header(&event_buf, 2);
-   ei_x_encode_long(&event_buf, XML_CDATA);
-   ei_x_encode_binary(&event_buf, s, len);
-   return NULL;
-}
-
-void *erlXML_StartNamespaceDeclHandler(expat_data *d,
-                                      const XML_Char *prefix,
-                                      const XML_Char *uri)
-{
-  int prefix_len;
-  char *buf;
-
-  /* From the expat documentation:
-     "For a default namespace declaration (xmlns='...'),
-     the prefix will be null ...
-     ... The URI will be null for the case where
-     the default namespace is being unset."
-
-     FIXME: I'm not quite sure what all that means */
-  if (uri == NULL)
-      return NULL;
-
-  ei_x_encode_list_header(&xmlns_buf, 1);
-  ei_x_encode_tuple_header(&xmlns_buf, 2);
-  if (prefix) {
-    prefix_len = strlen(prefix);
-    buf = driver_alloc(7 + prefix_len);
-    strcpy(buf, "xmlns:");
-    strcpy(buf+6, prefix);
-    ei_x_encode_binary(&xmlns_buf, buf, strlen(buf));
-    driver_free(buf);
-  } else {
-     ei_x_encode_binary(&xmlns_buf, "xmlns", strlen("xmlns"));
-  };
-  ei_x_encode_binary(&xmlns_buf, uri, strlen(uri));
-
-  return NULL;
-}
-
-static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
-{
-   expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
-   d->port = port;
-   d->parser = XML_ParserCreate_MM("UTF-8", &ms, "\n");
-   XML_SetUserData(d->parser, d);
-
-   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
-   XML_SetStartElementHandler(
-      d->parser, (XML_StartElementHandler)erlXML_StartElementHandler);
-   XML_SetEndElementHandler(
-      d->parser, (XML_EndElementHandler)erlXML_EndElementHandler);
-   XML_SetCharacterDataHandler(
-      d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);
-
-   XML_SetStartNamespaceDeclHandler(
-      d->parser, (XML_StartNamespaceDeclHandler) erlXML_StartNamespaceDeclHandler);
-   XML_SetReturnNSTriplet(d->parser, 1);
-
-   XML_SetDefaultHandler(d->parser, NULL);
-
-   return (ErlDrvData)d;
-}
-
-static void expat_erl_stop(ErlDrvData handle)
-{
-   XML_ParserFree(((expat_data *)handle)->parser);
-   driver_free((char*)handle);
-}
-
-static ErlDrvSSizeT expat_erl_control(ErlDrvData drv_data,
-                            unsigned int command,
-                            char *buf, ErlDrvSizeT len,
-                            char **rbuf, ErlDrvSizeT rlen)
-{
-   expat_data* d = (expat_data*)drv_data;
-   int res, errcode;
-   char *errstring;
-   ErlDrvBinary *b;
-   size_t size;
-
-   switch (command)
-   {
-      case PARSE_COMMAND:
-      case PARSE_FINAL_COMMAND:
-        ei_x_new_with_version(&event_buf);
-        ei_x_new(&xmlns_buf);
-        res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND);
-
-        if(!res)
-        {
-           errcode = XML_GetErrorCode(d->parser);
-           errstring = (char *)XML_ErrorString(errcode);
-
-           ei_x_encode_list_header(&event_buf, 1);
-           ei_x_encode_tuple_header(&event_buf, 2);
-           ei_x_encode_long(&event_buf, XML_ERROR);
-           ei_x_encode_tuple_header(&event_buf, 2);
-           ei_x_encode_long(&event_buf, errcode);
-           ei_x_encode_binary(&event_buf, errstring, strlen(errstring));
-        }
-
-        ei_x_encode_empty_list(&event_buf);
-
-        size = event_buf.index;
-
-        b = driver_alloc_binary(size);
-        memcpy(b->orig_bytes, event_buf.buff, size);
-
-        ei_x_free(&event_buf);
-        ei_x_free(&xmlns_buf);
-        *rbuf = (char *)b;
-        return size;
-      default:
-        return 0;
-   }
-}
-
-ErlDrvEntry expat_driver_entry = {
-   NULL,                       /* F_PTR init, N/A */
-   expat_erl_start,            /* L_PTR start, called when port is opened */
-   expat_erl_stop,             /* F_PTR stop, called when port is closed */
-   NULL,                       /* F_PTR output, called when erlang has sent */
-   NULL,                       /* F_PTR ready_input, called when input descriptor ready */
-   NULL,                       /* F_PTR ready_output, called when output descriptor ready */
-   "expat_erl",                        /* char *driver_name, the argument to open_port */
-   NULL,                       /* F_PTR finish, called when unloaded */
-   NULL,                       /* handle */
-   expat_erl_control,          /* F_PTR control, port_command callback */
-   NULL,                       /* F_PTR timeout, reserved */
-   NULL,                       /* F_PTR outputv, reserved */
-  /* Added in Erlang/OTP R15B: */
-  NULL,                 /* ready_async */
-  NULL,                 /* flush */
-  NULL,                 /* call */
-  NULL,                 /* event */
-  ERL_DRV_EXTENDED_MARKER,        /* extended_marker */
-  ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */
-  ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */
-  0,                    /* driver_flags */
-  NULL,                 /* handle2 */
-  NULL,                 /* process_exit */
-  NULL                  /* stop_select */
-};
-
-DRIVER_INIT(expat_erl) /* must match name in driver_entry */
-{
-    ms.malloc_fcn = driver_alloc;
-    ms.realloc_fcn = driver_realloc;
-    ms.free_fcn = driver_free;
-    return &expat_driver_entry;
-}
-
-
index 6a7f8d7b9b54f77f5dce811ede4368cdcaf67143..0403b56b4e721bfb4bec77ec848f237ccd7c0222 100644 (file)
@@ -33,6 +33,7 @@
         remove_user/3, is_user_exists/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -define(INIT_TIMEOUT, 60000).
 
index 78793bffb9f7930f14d6a44dcc513761b0f3c98c..fd14114ff958fb8c21cc485d25a09307b6b2de44 100644 (file)
@@ -40,6 +40,8 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
+-include("jlib.hrl").
 
 -record(state, {host, module, function}).
 
index f824ff740a2d8747f8acf8ab39ebc4e5d20d4ad8..5245dc65cacc89b43336150032c1d20fccb90ec4 100644 (file)
@@ -39,6 +39,7 @@
 %%-export([behaviour_info/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -record(ejabberd_module,
         {module_host = {undefined, <<"">>} :: {atom(), binary()},
index a5d2f9961bc8dcde893d5df4ea45a2c291a7571b..a600339989ea5df107988dd762c55f778823e760 100644 (file)
@@ -32,6 +32,7 @@
 -export([import_file/1, import_dir/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index bf08a476dc1282b4a6ea58840250fd76f2d5f7bc..560d36ab7153caa0d0104dd669e0a72b81f55853 100644 (file)
@@ -28,7 +28,9 @@
 
 -author('alexey@process-one.net').
 
--compile({no_auto_import, [{atom_to_binary, 2}]}).
+-compile({no_auto_import, [atom_to_binary/2,
+                           binary_to_integer/1,
+                           integer_to_binary/1]}).
 
 -export([make_result_iq_reply/1, make_error_reply/3,
         make_error_reply/2, make_error_element/2,
index 2eaf3684050c40afc76dce57d78ca86252988ded..ae37bb9d66d92ee6bcaeef7e6add6952fd142267 100644 (file)
@@ -37,6 +37,7 @@
         ping_item/4, ping_command/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index b6df44892365f83559d723898f11a12d6b76f72d..8d72b4bf7a4da0f3c25484f95950cede9db79957 100644 (file)
@@ -46,6 +46,7 @@
         announce_items/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 -include("adhoc.hrl").
 
index 5d5f33e99c4c1f770fa9681acb0dfeb4df1c7aea..2aaff7bae2348d5f42477e51687c68974a5204c1 100644 (file)
@@ -32,6 +32,7 @@
         process_iq_set/4, process_iq_get/5]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 4bec5f29e940bea22906351fb38187b40acd7fa5..c2f8d42f6a4aa3e5fe2c4ea41eb4af65d02ed84d 100644 (file)
@@ -52,6 +52,7 @@
         c2s_broadcast_recipients/5]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
@@ -462,42 +463,6 @@ make_my_disco_hash(Host) ->
       _Err -> <<"">>
     end.
 
--ifdef(HAVE_MD2).
-
-make_disco_hash(DiscoEls, Algo) ->
-    Concat = list_to_binary([concat_identities(DiscoEls),
-                             concat_features(DiscoEls), concat_info(DiscoEls)]),
-    jlib:encode_base64(case Algo of
-                           md2 -> sha:md2(Concat);
-                           md5 -> crypto:md5(Concat);
-                           sha1 -> crypto:sha(Concat);
-                           sha224 -> sha:sha224(Concat);
-                           sha256 -> sha:sha256(Concat);
-                           sha384 -> sha:sha384(Concat);
-                           sha512 -> sha:sha512(Concat)
-                       end).
-
-check_hash(Caps, Els) ->
-    case Caps#caps.hash of
-      <<"md2">> ->
-         Caps#caps.version == make_disco_hash(Els, md2);
-      <<"md5">> ->
-         Caps#caps.version == make_disco_hash(Els, md5);
-      <<"sha-1">> ->
-         Caps#caps.version == make_disco_hash(Els, sha1);
-      <<"sha-224">> ->
-         Caps#caps.version == make_disco_hash(Els, sha224);
-      <<"sha-256">> ->
-         Caps#caps.version == make_disco_hash(Els, sha256);
-      <<"sha-384">> ->
-         Caps#caps.version == make_disco_hash(Els, sha384);
-      <<"sha-512">> ->
-         Caps#caps.version == make_disco_hash(Els, sha512);
-      _ -> true
-    end.
-
--else.
-
 make_disco_hash(DiscoEls, Algo) ->
     Concat = list_to_binary([concat_identities(DiscoEls),
                              concat_features(DiscoEls), concat_info(DiscoEls)]),
@@ -527,8 +492,6 @@ check_hash(Caps, Els) ->
       _ -> true
     end.
 
--endif.
-
 concat_features(Els) ->
     lists:usort(lists:flatmap(fun (#xmlel{name =
                                              <<"feature">>,
index b868aa02261c6fb7ea96221574777c7f492d02a1..0a9338ac8c9e88bcd5d667a8190e6c08832a626b 100644 (file)
@@ -47,6 +47,7 @@
 -define(NS_FORWARD, <<"urn:xmpp:forward:0">>).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 -define(PROCNAME, ?MODULE).
 -define(TABLE, carboncopy).
index 3d2b7d267b321ec107d482c67061a74894bbbbd5..f98bfc78819e475d8c694a897632df5528211567 100644 (file)
@@ -40,6 +40,7 @@
         adhoc_sm_items/4, adhoc_sm_commands/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 3665386322b7b040898207785ced2ee036410b88..c4d482d02207f0747224c0ea1bd4b0b222da96c4 100644 (file)
@@ -33,6 +33,7 @@
 -export([start/2, stop/1, process_local_iq/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index c883e0782409985610162e73f895fdd8c6324495..d6225168680633d7a626f21b9c3cd09747c6ec9c 100644 (file)
@@ -39,6 +39,7 @@
         register_extra_domain/2, unregister_extra_domain/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 15df692440178e3d0374feba165eadec04daf31d..077a4de4945c3604f25bd050859168322aff53fd 100644 (file)
@@ -41,6 +41,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/web/mod_http_bind.erl
rename to src/mod_http_bind.erl
index 164c07d3371c3dc7089fa36e984161934778e70c..dcaa8a91ae8f30497062d4fc1044275d3f7e116e 100644 (file)
@@ -41,6 +41,7 @@
 -export([start/2, stop/1, process/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/web/mod_http_fileserver.erl
rename to src/mod_http_fileserver.erl
index 98206a5f0519f4b52c50806051acaadd5c4553de..f16256d4f4b3ebcf76c441ba0f7cdbe24c896c17 100644 (file)
@@ -48,6 +48,7 @@
 -export([reopen_log/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 073dd5af07dc5c08d7a74b0e72a8e25ebc477e22..3af5aaac0d528927427eab26c012e91d0e2eaa3f 100644 (file)
@@ -41,6 +41,7 @@
 -export([is_ip_in_c2s_blacklist/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -define(PROCNAME, ?MODULE).
 
@@ -70,7 +71,6 @@ preinit(Parent, State) ->
 stop(_Host) -> ok.
 
 init(State) ->
-    inets:start(),
     ets:new(bl_c2s,
            [named_table, public, {keypos, #bl_c2s.ip}]),
     update_bl_c2s(),
similarity index 99%
rename from src/mod_irc/mod_irc.erl
rename to src/mod_irc.erl
index 53069671d72dfb063a31f8973ba82f6b012f7325..9d9246fad3cf51b132b26a16ebeb4676bbe3ef3e 100644 (file)
@@ -41,6 +41,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
@@ -111,7 +112,7 @@ stop(Host) ->
 %% Description: Initiates the server
 %%--------------------------------------------------------------------
 init([Host, Opts]) ->
-    iconv:start(),
+    ejabberd:start_app(p1_iconv),
     MyHost = gen_mod:get_opt_host(Host, Opts,
                                  <<"irc.@HOST@">>),
     case gen_mod:db_type(Opts) of
diff --git a/src/mod_irc/Makefile.in b/src/mod_irc/Makefile.in
deleted file mode 100644 (file)
index 9dcf9f1..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @LIBICONV@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-ifeq ($(shell uname),Darwin)
-    DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-endif
-ifeq ($(shell uname),SunOs)
-    DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
-endif
-
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-ERLSHLIBS = ../iconv_erl.so
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-all:    $(BEAMS) $(ERLSHLIBS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-#all:  $(ERLSHLIBS)
-#      erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
-
-$(ERLSHLIBS):  ../%.so:        %.c
-       $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) \
-               $(subst ../,,$(subst .so,.c,$@)) \
-               $(LIBS) \
-               $(ERLANG_CFLAGS) \
-               $(ERLANG_LIBS) \
-               -o $@ \
-               $(DYNAMIC_LIB_CFLAGS)
-
-clean:
-       rm -f $(BEAMS) $(ERLSHLIBS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/mod_irc/Makefile.win32 b/src/mod_irc/Makefile.win32
deleted file mode 100644 (file)
index fb06711..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\iconv.beam ..\mod_irc.beam ..\mod_irc_connection.beam
-
-SOURCE = iconv_erl.c
-OBJECT = iconv_erl.o
-DLL    = $(OUTDIR)\iconv_erl.dll
-
-ALL : $(DLL) $(BEAMS)
-
-CLEAN :
-       -@erase $(DLL)
-       -@erase $(OUTDIR)\iconv_erl.exp
-       -@erase $(OUTDIR)\iconv_erl.lib
-       -@erase $(OBJECT)
-       -@erase $(BEAMS)
-
-$(OUTDIR)\iconv.beam : iconv.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) iconv.erl
-
-$(OUTDIR)\mod_irc.beam : mod_irc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_irc.erl
-
-$(OUTDIR)\mod_irc_connection.beam : mod_irc_connection.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_irc_connection.erl
-
-CC=cl.exe
-CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(ICONV_DIR)\include"
-
-LD=link.exe
-LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(ICONV_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
-
-$(DLL) : $(OBJECT)
-       $(LD) $(LD_FLAGS) -out:$@ $<
-
-$(OBJECT) : $(SOURCE)
-       $(CC) $(CC_FLAGS) -c -Fo$@ $<
-
diff --git a/src/mod_irc/iconv.erl b/src/mod_irc/iconv.erl
deleted file mode 100644 (file)
index 4d81805..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : iconv.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : Interface to libiconv
-%%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(iconv).
-
--author('alexey@process-one.net').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0, convert/3]).
-
-%% Internal exports, call-back functions.
--export([init/1, handle_call/3, handle_cast/2,
-        handle_info/2, code_change/3, terminate/2]).
-
-start() ->
-    gen_server:start({local, ?MODULE}, ?MODULE, [], []).
-
-start_link() ->
-    gen_server:start_link({local, ?MODULE}, ?MODULE, [],
-                         []).
-
-init([]) ->
-    case erl_ddll:load_driver(ejabberd:get_so_path(),
-                             iconv_erl)
-       of
-      ok -> ok;
-      {error, already_loaded} -> ok
-    end,
-    Port = open_port({spawn, "iconv_erl"}, []),
-    ets:new(iconv_table, [set, public, named_table]),
-    ets:insert(iconv_table, {port, Port}),
-    {ok, Port}.
-
-%%% --------------------------------------------------------
-%%% The call-back functions.
-%%% --------------------------------------------------------
-
-handle_call(_, _, State) -> {noreply, State}.
-
-handle_cast(_, State) -> {noreply, State}.
-
-handle_info({'EXIT', Port, Reason}, Port) ->
-    {stop, {port_died, Reason}, Port};
-handle_info({'EXIT', _Pid, _Reason}, Port) ->
-    {noreply, Port};
-handle_info(_, State) -> {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
-
-terminate(_Reason, Port) -> Port ! {self, close}, ok.
-
--spec convert(binary(), binary(), binary()) -> binary().
-
-convert(From, To, String) ->
-    [{port, Port} | _] = ets:lookup(iconv_table, port),
-    Bin = term_to_binary({From, To, String}),
-    BRes = port_control(Port, 1, Bin),
-    (BRes).
diff --git a/src/mod_irc/iconv_erl.c b/src/mod_irc/iconv_erl.c
deleted file mode 100644 (file)
index 20d9389..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013   ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <ei.h>
-#include <iconv.h>
-
-/*
- * R15B changed several driver callbacks to use ErlDrvSizeT and
- * ErlDrvSSizeT typedefs instead of int.
- * This provides missing typedefs on older OTP versions.
- */
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int ErlDrvSizeT;
-typedef int ErlDrvSSizeT;
-#endif
-
-typedef struct {
-      ErlDrvPort port;
-      iconv_t cd;
-} iconv_data;
-
-
-static ErlDrvData iconv_erl_start(ErlDrvPort port, char *buff)
-{
-   iconv_data* d = (iconv_data*)driver_alloc(sizeof(iconv_data));
-   d->port = port;
-   d->cd = NULL;
-
-   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-   
-   return (ErlDrvData)d;
-}
-
-static void iconv_erl_stop(ErlDrvData handle)
-{
-   driver_free((char*)handle);
-}
-
-static ErlDrvSSizeT iconv_erl_control(ErlDrvData drv_data,
-                            unsigned int command,
-                            char *buf, ErlDrvSizeT len,
-                            char **rbuf, ErlDrvSizeT rlen)
-{
-   int i;
-   int size;
-   int index = 0;
-   int avail;
-   size_t inleft, outleft;
-   ErlDrvBinary *b;
-   char *from, *to, *string, *stmp, *rstring, *rtmp;
-   iconv_t cd;
-   int invalid_utf8_as_latin1 = 0;
-
-   ei_decode_version(buf, &index, &i);
-   ei_decode_tuple_header(buf, &index, &i);
-   ei_get_type(buf, &index, &i, &size);
-   from = driver_alloc(size + 1); 
-   ei_decode_string(buf, &index, from);
-
-   ei_get_type(buf, &index, &i, &size);
-   to = driver_alloc(size + 1); 
-   ei_decode_string(buf, &index, to);
-  
-   ei_get_type(buf, &index, &i, &size);
-   stmp = string = driver_alloc(size + 1); 
-   ei_decode_string(buf, &index, string);
-
-   /* Special mode: parse as UTF-8 if possible; otherwise assume it's
-      Latin-1.  Makes no difference when encoding. */
-   if (strcmp(from, "utf-8+latin-1") == 0) {
-      from[5] = '\0';
-      invalid_utf8_as_latin1 = 1;
-   }
-   if (strcmp(to, "utf-8+latin-1") == 0) {
-      to[5] = '\0';
-   }
-   cd = iconv_open(to, from);
-
-   if (cd == (iconv_t) -1) {
-      cd = iconv_open("ascii", "ascii");
-      if (cd == (iconv_t) -1) {
-        *rbuf = (char*)(b = driver_alloc_binary(size));
-        memcpy(b->orig_bytes, string, size);
-
-        driver_free(from);
-        driver_free(to);
-        driver_free(string);
-
-        return size;
-      }
-   }
-   
-   outleft = avail = 4*size;
-   inleft = size;
-   rtmp = rstring = driver_alloc(avail);
-   while (inleft > 0) {
-      if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) {
-        if (invalid_utf8_as_latin1 && (*stmp & 0x80) && outleft >= 2) {
-           /* Encode one byte of (assumed) Latin-1 into two bytes of UTF-8 */
-           *rtmp++ = 0xc0 | ((*stmp & 0xc0) >> 6);
-           *rtmp++ = 0x80 | (*stmp & 0x3f);
-           outleft -= 2;
-        }
-        stmp++;
-        inleft--;
-      }
-   }
-   
-   size = rtmp - rstring;
-
-   *rbuf = (char*)(b = driver_alloc_binary(size));
-   memcpy(b->orig_bytes, rstring, size);
-
-   driver_free(from);
-   driver_free(to);
-   driver_free(string);
-   driver_free(rstring);
-   iconv_close(cd);
-   
-   return size;
-}
-
-
-
-ErlDrvEntry iconv_driver_entry = {
-   NULL,                       /* F_PTR init, N/A */
-   iconv_erl_start,          /* L_PTR start, called when port is opened */
-   iconv_erl_stop,           /* F_PTR stop, called when port is closed */
-   NULL,         /* F_PTR output, called when erlang has sent */
-   NULL,                       /* F_PTR ready_input, called when input descriptor ready */
-   NULL,                       /* F_PTR ready_output, called when output descriptor ready */
-   "iconv_erl",              /* char *driver_name, the argument to open_port */
-   NULL,                       /* F_PTR finish, called when unloaded */
-   NULL,                       /* handle */
-   iconv_erl_control,          /* F_PTR control, port_command callback */
-   NULL,                       /* F_PTR timeout, reserved */
-   NULL,                       /* F_PTR outputv, reserved */
-  /* Added in Erlang/OTP R15B: */
-  NULL,                 /* ready_async */
-  NULL,                 /* flush */
-  NULL,                 /* call */
-  NULL,                 /* event */
-  ERL_DRV_EXTENDED_MARKER,        /* extended_marker */
-  ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */
-  ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */
-  0,                    /* driver_flags */
-  NULL,                 /* handle2 */
-  NULL,                 /* process_exit */
-  NULL                  /* stop_select */
-};
-
-DRIVER_INIT(iconv_erl) /* must match name in driver_entry */
-{
-    return &iconv_driver_entry;
-}
-
-
similarity index 99%
rename from src/mod_irc/mod_irc_connection.erl
rename to src/mod_irc_connection.erl
index ba0cb4345d5628a76706ab2a4718cce13a61027c..c37ca7cb4bca23c96ac7ea42c08616ee24272774 100644 (file)
@@ -41,6 +41,7 @@
         code_change/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index e8df5a270d91d44d0e1aba45dee14c82c49bd9cd..28fcda63a31f8cb1e367b55ad7c23c88631a802a 100644 (file)
@@ -35,6 +35,7 @@
         store_last_info/4, get_last_info/2, remove_user/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/mod_muc/mod_muc.erl
rename to src/mod_muc.erl
index 6587cc5d001732d345307ab21141438fb4ae4bac..05becd20bd309ad731edf0b8d5de4c29daaca8cf 100644 (file)
@@ -50,6 +50,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
diff --git a/src/mod_muc/Makefile.in b/src/mod_muc/Makefile.in
deleted file mode 100644 (file)
index 5ede5e5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-ifeq (@transient_supervisors@, false)
-       EFLAGS+=-DNO_TRANSIENT_SUPERVISORS
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/mod_muc/Makefile.win32 b/src/mod_muc/Makefile.win32
deleted file mode 100644 (file)
index 5107b10..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\mod_muc.beam ..\mod_muc_log.beam ..\mod_muc_room.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\mod_muc.beam : mod_muc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc.erl
-
-$(OUTDIR)\mod_muc_log.beam : mod_muc_log.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc_log.erl
-
-$(OUTDIR)\mod_muc_room.beam : mod_muc_room.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc_room.erl
similarity index 99%
rename from src/mod_muc/mod_muc_log.erl
rename to src/mod_muc_log.erl
index ec62c85fdd910969f43762297d258576a7322a25..97d99214504b60335dade69fd3c8bdcddd622f04 100644 (file)
@@ -41,6 +41,7 @@
         handle_info/2, terminate/2, code_change/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/mod_muc/mod_muc_room.erl
rename to src/mod_muc_room.erl
index 61ec57766d50b5a05f523ff137fe865dd3bf2737..7c9bdd41b3cbd0ac78428c5421118dfe022aac86 100644 (file)
@@ -47,6 +47,7 @@
         code_change/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 4670b9b8499c7d5e8fe11a7809fb4210ee2de35f..bf7da6cd3bad3aaaba80e983e1b3982b8525a767 100644 (file)
         webadmin_user_parse_query/5]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
--include("web/ejabberd_http.hrl").
+-include("ejabberd_http.hrl").
 
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_web_admin.hrl").
 
 -record(offline_msg,
        {us = {<<"">>, <<"">>} :: {binary(), binary()},
index c3bfd7b322818161b180d27fd5e7efa23d88ea6f..078b0d13dc34aad137c8b22affb62c13d08ca008 100644 (file)
 -behavior(gen_server).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
 -define(SUPERVISOR, ejabberd_sup).
 
--define(NS_PING, <<"urn:xmpp:ping">>).
-
 -define(DEFAULT_SEND_PINGS, false).
 
 -define(DEFAULT_PING_INTERVAL, 60).
index 9246f8d55d1206d3118c560a5d6537d0c1eb9d01..30f5308c085667ed531d72f55fe22e360f1dc936 100644 (file)
@@ -31,6 +31,7 @@
 -export([start/2, stop/1, check_packet/6]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 22c5ce77dcc0064a0cd381d176ef45cb38a1647e..4c03159f521da420872c1f7d86439ffaa306f2f4 100644 (file)
@@ -47,6 +47,7 @@
         sql_set_privacy_list/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 45af660a2b8a380d9b17a981e3606b9e84eb79d8..19e1e038ea6cb242211c81615a836a0442d54fd9 100644 (file)
@@ -34,6 +34,7 @@
         remove_user/2, get_data/2, export/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
diff --git a/src/mod_proxy65/Makefile.in b/src/mod_proxy65/Makefile.in
deleted file mode 100644 (file)
index 3fc94c6..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/mod_proxy65/Makefile.win32 b/src/mod_proxy65/Makefile.win32
deleted file mode 100644 (file)
index 7683097..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\mod_proxy65.beam ..\mod_proxy65_lib.beam ..\mod_proxy65_service.beam ..\mod_proxy65_sm.beam ..\mod_proxy65_stream.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\mod_proxy65.beam : mod_proxy65.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65.erl
-
-$(OUTDIR)\mod_proxy65_service.beam : mod_proxy65_service.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_service.erl
-
-$(OUTDIR)\mod_proxy65_sm.beam : mod_proxy65_sm.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_sm.erl
-
-$(OUTDIR)\mod_proxy65_stream.beam : mod_proxy65_stream.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_stream.erl
-
-$(OUTDIR)\mod_proxy65_lib.beam : mod_proxy65_lib.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_lib.erl
similarity index 99%
rename from src/mod_proxy65/mod_proxy65_service.erl
rename to src/mod_proxy65_service.erl
index 22ac6cde64d5f3ec51aad89f00861e9d0d70deb2..1e008efa8f9ad199ff2226ffe59e5566b07e07de 100644 (file)
@@ -39,6 +39,7 @@
         delete_listener/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/mod_proxy65/mod_proxy65_stream.erl
rename to src/mod_proxy65_stream.erl
index 1eca99b39e0f7cba44d382921c6968f93c12ac0a..9b861f4dbc4dd33b8332ce6b3a4a5bddfe78f5c5 100644 (file)
@@ -45,6 +45,7 @@
 -include("mod_proxy65.hrl").
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -define(WAIT_TIMEOUT, 60000).
 
similarity index 99%
rename from src/mod_pubsub/mod_pubsub.erl
rename to src/mod_pubsub.erl
index 53b32d9de25d41b2ecfc95d8e1b9921ed7d41b15..2e8e8fa8b4318a47b43eb295e43b68111812d7d1 100644 (file)
@@ -54,6 +54,7 @@
 -behaviour(gen_mod).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("adhoc.hrl").
 
diff --git a/src/mod_pubsub/Makefile.in b/src/mod_pubsub/Makefile.in
deleted file mode 100644 (file)
index 88bf2ba..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-ERLBEHAVS = gen_pubsub_node.erl gen_pubsub_nodetree.erl
-SOURCES_ALL = $(wildcard *.erl)
-SOURCES = $(filter-out $(ERLBEHAVS),$(SOURCES_ALL))
-ERLBEHAVBEAMS = $(addprefix $(OUTDIR)/,$(ERLBEHAVS:.erl=.beam))
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all: mod_pubsub_odbc.erl $(ERLBEHAVBEAMS) $(BEAMS)
-
-$(BEAMS): $(ERLBEHAVBEAMS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-mod_pubsub_odbc.erl:
-       patch -o mod_pubsub_odbc.erl mod_pubsub.erl pubsub_odbc.patch
-
-TAGS:
-       etags *.erl
-
diff --git a/src/mod_pubsub/Makefile.win32 b/src/mod_pubsub/Makefile.win32
deleted file mode 100644 (file)
index 8308f24..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS =  ..\gen_pubsub_node.beam ..\gen_pubsub_nodetree.beam ..\mod_pubsub.beam ..\mod_pubsub_odbc.beam ..\node_buddy.beam ..\node_club.beam ..\node_dag.beam ..\node_dispatch.beam ..\node_flat.beam ..\node_flat_odbc.beam ..\node_hometree.beam ..\node_hometree_odbc.beam ..\node_mb.beam ..\node_pep.beam ..\node_pep_odbc.beam ..\node_private.beam ..\node_public.beam ..\nodetree_dag.beam ..\nodetree_tree.beam ..\nodetree_tree_odbc.beam ..\nodetree_virtual.beam ..\pubsub_db_odbc.beam ..\pubsub_index.beam ..\pubsub_subscription.beam ..\pubsub_subscription_odbc.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\gen_pubsub_node.beam : gen_pubsub_node.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) gen_pubsub_node.erl
-
-$(OUTDIR)\gen_pubsub_nodetree.beam : gen_pubsub_nodetree.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) gen_pubsub_nodetree.erl
-
-$(OUTDIR)\mod_pubsub.beam : mod_pubsub.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_pubsub.erl
-
-$(OUTDIR)\mod_pubsub_odbc.beam : mod_pubsub_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_pubsub_odbc.erl
-
-$(OUTDIR)\node_buddy.beam : node_buddy.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_buddy.erl
-
-$(OUTDIR)\node_club.beam : node_club.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_club.erl
-
-$(OUTDIR)\node_dag.beam : node_dag.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_dag.erl
-
-$(OUTDIR)\node_dispatch.beam : node_dispatch.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_dispatch.erl
-
-$(OUTDIR)\node_flat.beam : node_flat.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_flat.erl
-
-$(OUTDIR)\node_flat_odbc.beam : node_flat_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_flat_odbc.erl
-
-$(OUTDIR)\node_hometree.beam : node_hometree.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_hometree.erl
-
-$(OUTDIR)\node_hometree_odbc.beam : node_hometree_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_hometree_odbc.erl
-
-$(OUTDIR)\node_mb.beam : node_mb.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_mb.erl
-
-$(OUTDIR)\node_pep.beam : node_pep.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_pep.erl
-
-$(OUTDIR)\node_pep_odbc.beam : node_pep_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_pep_odbc.erl
-
-$(OUTDIR)\node_private.beam : node_private.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_private.erl
-
-$(OUTDIR)\node_public.beam : node_public.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) node_public.erl
-
-$(OUTDIR)\nodetree_dag.beam : nodetree_dag.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_dag.erl
-
-$(OUTDIR)\nodetree_tree.beam : nodetree_tree.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_tree.erl
-
-$(OUTDIR)\nodetree_tree_odbc.beam : nodetree_tree_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_tree_odbc.erl
-
-$(OUTDIR)\nodetree_virtual.beam : nodetree_virtual.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_virtual.erl
-
-$(OUTDIR)\pubsub_db_odbc.beam : pubsub_db_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_db_odbc.erl
-
-$(OUTDIR)\pubsub_index.beam : pubsub_index.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_index.erl
-
-$(OUTDIR)\pubsub_subscription.beam : pubsub_subscription.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_subscription.erl
-
-$(OUTDIR)\pubsub_subscription_odbc.beam : pubsub_subscription_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_subscription_odbc.erl
similarity index 99%
rename from src/mod_pubsub/mod_pubsub_odbc.erl
rename to src/mod_pubsub_odbc.erl
index 51b411dc0dac080006e83be10af10fba8831b555..d9f1b71be0f5c762417b990c4deb8775c194007a 100644 (file)
@@ -54,6 +54,7 @@
 -behaviour(gen_mod).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("adhoc.hrl").
 
index 9acc71a22392d8576ee2c5ff1784667fa579be5a..024acc1b6a624f31188fcc7f69dd68326c04bb21 100644 (file)
@@ -35,6 +35,7 @@
         process_iq/3, send_registration_notifications/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
similarity index 99%
rename from src/web/mod_register_web.erl
rename to src/mod_register_web.erl
index 0ccba99458e692f25c1598a731454e26a554fe15..841685a94ac05376111305504c25e17786e0128c 100644 (file)
@@ -59,6 +59,7 @@
 -export([start/2, stop/1, process/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index dfaf7496e4f4d135b310dbe98629d69d46835831..2295933f8196825626ab0688051412c5d0e6e43a 100644 (file)
          record_to_string/1, groups_to_string/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
 -include("mod_roster.hrl").
 
--include("web/ejabberd_http.hrl").
+-include("ejabberd_http.hrl").
 
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_web_admin.hrl").
 
 -export_type([subscription/0]).
 
index 2a0def2b5a286d64193adaa113dc0e67bedac164..82497a60986d82009c152697d26a55b25ec8b718 100644 (file)
@@ -36,6 +36,7 @@
         log_user_receive/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 057deba20399f668b1ed7b59a1d6da5b3449452e..2501ef2b520f71e53ac3cd407a97d9c66ebfd1e8 100644 (file)
         add_user_to_group/3, remove_user_from_group/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
 -include("mod_roster.hrl").
 
--include("web/ejabberd_http.hrl").
+-include("ejabberd_http.hrl").
 
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_web_admin.hrl").
 
 -record(sr_group, {group_host = {<<"">>, <<"">>} :: {'$1' | binary(), '$2' | binary()},
                    opts = [] :: list() | '_' | '$2'}).
index 3ddba08bc46d5dcc732f7f73f5172214c71c5630..322909a2c74dd6320b6e9804d6bbf2c14786b651 100644 (file)
         out_subscription/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 -include("mod_roster.hrl").
 
--include("eldap/eldap.hrl").
+-include("eldap.hrl").
 
 -define(CACHE_SIZE, 1000).
 
index fbaa165e8d67dbaa0f54984497c75fe9f330ff89..b1ae44d04f5ea826880a928dd9c3cdc7e34b2448 100644 (file)
@@ -34,6 +34,7 @@
         process_sm_iq/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index f988626fd88597d9c82d24107b406d8b2e1b926f..a359289759362960506abecfe21d8108e3faed80 100644 (file)
@@ -33,6 +33,7 @@
 -export([start/2, stop/1, process_local_iq/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 -include("jlib.hrl").
 
 start(Host, Opts) ->
index a97391e7d00fd9a8ba40565d1d46d450f1b5b6d3..d6c8363d7f285d0f8152985334985de296c71513 100644 (file)
@@ -37,6 +37,7 @@
                                % TODO: Remove once XEP-0090 is Obsolete
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 901098398a3b50785ee3f9bffca821c915ca0405..fa657df5d55233957745b76aa9d6b62335251ce1 100644 (file)
@@ -35,6 +35,7 @@
         remove_user/2, export/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index be9bc7c5313e27dd7626160756b97234f3dfeaf6..7711353d2dfd819e7b733c46324096767a270657 100644 (file)
@@ -41,8 +41,9 @@
         remove_user/1, route/4]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
--include("eldap/eldap.hrl").
+-include("eldap.hrl").
 
 -include("jlib.hrl").
 
index f1747859f772e0d770fc9ed1c31580cef076f53d..d98cdfcc361a2a3fe6bfce0fce54837aeab6d6c7 100644 (file)
@@ -16,6 +16,7 @@
 -export([update_presence/3, vcard_set/3, export/1]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
index 088961a6b1a28e1f86799e34b8faf3feb27bcb92..a36f62889bcbd8343e7a406966706464b22046be 100644 (file)
@@ -33,6 +33,7 @@
 -export([start/2, stop/1, process_local_iq/3]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("jlib.hrl").
 
diff --git a/src/mysql/COPYING b/src/mysql/COPYING
deleted file mode 100644 (file)
index bf94bdf..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2001-2003 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 
- * 3. Neither the name of the Institute nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-  Copyright (c) 2004, Sektionen för IT och media, Stockholms
-                      universitet
-  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or
-  without modification, are permitted provided that the following
-  conditions are met:
-
-  1. Redistributions of source code must retain the above
-     copyright notice, this list of conditions and the following
-     disclaimer.
-
-  2. Redistributions in binary form must reproduce the above
-     copyright notice, this list of conditions and the following
-     disclaimer in the documentation and/or other materials
-     provided with the distribution.
-
-  3. Neither the name of the author nor the names of its
-     contributors may be used to endorse or promote products
-     derived from this software without specific prior written
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/mysql/Makefile.in b/src/mysql/Makefile.in
deleted file mode 100644 (file)
index e77da84..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id: Makefile.in 1453 2008-07-16 16:58:42Z badlop $
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/mysql/Makefile.win32 b/src/mysql/Makefile.win32
deleted file mode 100644 (file)
index e70aba9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\stun_codec.beam ..\ejabberd_stun.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\stun_codec.beam : stun_codec.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) stun_codec.erl
-
-$(OUTDIR)\ejabberd_stun.beam : ejabberd_stun.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_stun.erl
diff --git a/src/mysql/mysql.erl b/src/mysql/mysql.erl
deleted file mode 100644 (file)
index 2920b45..0000000
+++ /dev/null
@@ -1,692 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : mysql.erl
-%%% Author  : Magnus Ahltorp <ahltorp@nada.kth.se>
-%%% Descrip.: MySQL client.
-%%%
-%%% Created :  4 Aug 2005 by Magnus Ahltorp <ahltorp@nada.kth.se>
-%%%
-%%% Copyright (c) 2001-2004 Kungliga Tekniska Högskolan
-%%% See the file COPYING
-%%%
-%%% Usage:
-%%%
-%%%
-%%% Call one of the start-functions before any call to fetch/2
-%%%
-%%%   start_link(Id, Host, User, Password, Database)
-%%%   start_link(Id, Host, Port, User, Password, Database)
-%%%   start_link(Id, Host, User, Password, Database, LogFun)
-%%%   start_link(Id, Host, Port, User, Password, Database, LogFun)
-%%%
-%%% Id is a connection group identifier. If you want to have more
-%%% than one connection to a server (or a set of MySQL replicas),
-%%% add more with
-%%%
-%%%   connect(Id, Host, Port, User, Password, Database, Reconnect)
-%%%
-%%% use 'undefined' as Port to get default MySQL port number (3306).
-%%% MySQL querys will be sent in a per-Id round-robin fashion.
-%%% Set Reconnect to 'true' if you want the dispatcher to try and
-%%% open a new connection, should this one die.
-%%%
-%%% When you have a mysql_dispatcher running, this is how you make a
-%%% query :
-%%%
-%%%   fetch(Id, "select * from hello") -> Result
-%%%     Result = {data, MySQLRes} | {updated, MySQLRes} |
-%%%              {error, MySQLRes}
-%%%
-%%% Actual data can be extracted from MySQLRes by calling the following API
-%%% functions:
-%%%     - on data received:
-%%%          FieldInfo = mysql:get_result_field_info(MysqlRes)
-%%%          AllRows   = mysql:get_result_rows(MysqlRes)
-%%%         with FieldInfo = list() of {Table, Field, Length, Name}
-%%%          and AllRows   = list() of list() representing records
-%%%     - on update:
-%%%          Affected  = mysql:get_result_affected_rows(MysqlRes)
-%%%         with Affected  = integer()
-%%%     - on error:
-%%%          Reason    = mysql:get_result_reason(MysqlRes)
-%%%         with Reason    = string()
-%%%
-%%% If you just want a single MySQL connection, or want to manage your
-%%% connections yourself, you can use the mysql_conn module as a
-%%% stand-alone single MySQL connection. See the comment at the top of
-%%% mysql_conn.erl.
-%%%
-%%%-------------------------------------------------------------------
--module(mysql).
-
--behaviour(gen_server).
-
-%%--------------------------------------------------------------------
-%% External exports
-%%--------------------------------------------------------------------
--export([start_link/5,
-        start_link/6,
-        start_link/7,
-
-        fetch/2,
-        fetch/3,
-
-        get_result_field_info/1,
-        get_result_rows/1,
-        get_result_affected_rows/1,
-        get_result_reason/1,
-
-        quote/1,
-        asciz_binary/2,
-
-        connect/7,
-        stop/0,
-
-     gc_each/1
-       ]).
-
-%%--------------------------------------------------------------------
-%% Internal exports - just for mysql_* modules
-%%--------------------------------------------------------------------
--export([log/3,
-        log/4
-       ]).
-
-%%--------------------------------------------------------------------
-%% Internal exports - gen_server callbacks
-%%--------------------------------------------------------------------
--export([init/1,
-        handle_call/3,
-        handle_cast/2,
-        handle_info/2,
-        terminate/2,
-        code_change/3
-       ]).
-
-%%--------------------------------------------------------------------
-%% Records
-%%--------------------------------------------------------------------
--include("mysql.hrl").
--record(state, {
-         conn_list,    %% list() of mysql_connection record()
-         log_fun,      %% undefined | function for logging,
-      gc_tref   %% undefined | timer:TRef
-        }).
-
--record(mysql_connection, {
-         id,           %% term(), user of 'mysql' modules id of this socket group
-         conn_pid,     %% pid(), mysql_conn process
-         reconnect,    %% true | false, should mysql_dispatcher try to reconnect if this connection dies?
-         host,         %% undefined | string()
-         port,         %% undefined | integer()
-         user,         %% undefined | string()
-         password,     %% undefined | string()
-         database      %% undefined | string()
-        }).
-
-%%--------------------------------------------------------------------
-%% Macros
-%%--------------------------------------------------------------------
--define(SERVER, mysql_dispatcher).
--define(CONNECT_TIMEOUT, 5000).
--define(LOCAL_FILES, 128).
-
--define(PORT, 3306).
-
-
-%%====================================================================
-%% External functions
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: start_link(Id, Host, User, Password, Database)
-%%           start_link(Id, Host, Port, User, Password, Database)
-%%           start_link(Id, Host, User, Password, Database, LogFun)
-%%           start_link(Id, Host, Port, User, Password, Database,
-%%                      LogFun)
-%%           Id       = term(), first connection-group Id
-%%           Host     = string()
-%%           Port     = integer()
-%%           User     = string()
-%%           Password = string()
-%%           Database = string()
-%%           LogFun   = undefined | function() of arity 3
-%% Descrip.: Starts the MySQL client gen_server process.
-%% Returns : {ok, Pid} | ignore | {error, Error}
-%%--------------------------------------------------------------------
-start_link(Id, Host, User, Password, Database) when is_list(Host), is_list(User), is_list(Password),
-                                                   is_list(Database) ->
-    start_link(Id, Host, ?PORT, User, Password, Database, undefined).
-
-start_link(Id, Host, Port, User, Password, Database) when is_list(Host), is_integer(Port), is_list(User),
-                                                         is_list(Password), is_list(Database) ->
-    start_link(Id, Host, Port, User, Password, Database, undefined);
-
-start_link(Id, Host, User, Password, Database, LogFun) when is_list(Host), is_list(User), is_list(Password),
-                                                           is_list(Database) ->
-    start_link(Id, Host, ?PORT, User, Password, Database, LogFun).
-
-start_link(Id, Host, Port, User, Password, Database, LogFun) when is_list(Host), is_integer(Port), is_list(User),
-                                                                 is_list(Password), is_list(Database) ->
-    crypto:start(),
-    gen_server:start_link({local, ?SERVER}, ?MODULE, [Id, Host, Port, User, Password, Database, LogFun], []).
-
-stop() ->
-    gen_server:call(?SERVER, stop).
-
-gc_each(Millisec) ->
-    gen_server:call(?SERVER, {gc_each, Millisec}).
-
-%%--------------------------------------------------------------------
-%% Function: fetch(Id, Query)
-%%           fetch(Id, Query, Timeout)
-%%           Id      = term(), connection-group Id
-%%           Query   = string(), MySQL query in verbatim
-%%           Timeout = integer() | infinity, gen_server timeout value
-%% Descrip.: Send a query and wait for the result.
-%% Returns : {data, MySQLRes}    |
-%%           {updated, MySQLRes} |
-%%           {error, MySQLRes}
-%%           MySQLRes = term()
-%%--------------------------------------------------------------------
-fetch(Id, Query) when is_list(Query) ->
-    gen_server:call(?SERVER, {fetch, Id, Query}).
-fetch(Id, Query, Timeout) when is_list(Query) ->
-    gen_server:call(?SERVER, {fetch, Id, Query}, Timeout).
-
-%%--------------------------------------------------------------------
-%% Function: get_result_field_info(MySQLRes)
-%%           MySQLRes = term(), result of fetch function on "data"
-%% Descrip.: Extract the FieldInfo from MySQL Result on data received
-%% Returns : FieldInfo
-%%           FieldInfo = list() of {Table, Field, Length, Name}
-%%--------------------------------------------------------------------
-get_result_field_info(#mysql_result{fieldinfo = FieldInfo}) ->
-    FieldInfo.
-
-%%--------------------------------------------------------------------
-%% Function: get_result_rows(MySQLRes)
-%%           MySQLRes = term(), result of fetch function on "data"
-%% Descrip.: Extract the Rows from MySQL Result on data received
-%% Returns : Rows
-%%           Rows = list() of list() representing records
-%%--------------------------------------------------------------------
-get_result_rows(#mysql_result{rows=AllRows}) ->
-    AllRows.
-
-%%--------------------------------------------------------------------
-%% Function: get_result_affected_rows(MySQLRes)
-%%           MySQLRes = term(), result of fetch function on "updated"
-%% Descrip.: Extract the Rows from MySQL Result on update
-%% Returns : AffectedRows
-%%           AffectedRows = integer()
-%%--------------------------------------------------------------------
-get_result_affected_rows(#mysql_result{affectedrows=AffectedRows}) ->
-    AffectedRows.
-
-%%--------------------------------------------------------------------
-%% Function: get_result_reason(MySQLRes)
-%%           MySQLRes = term(), result of fetch function on "error"
-%% Descrip.: Extract the error Reason from MySQL Result on error
-%% Returns : Reason
-%%           Reason    = string()
-%%--------------------------------------------------------------------
-get_result_reason(#mysql_result{error=Reason}) ->
-    Reason.
-
-%%--------------------------------------------------------------------
-%% Function: quote(String)
-%%           String = string()
-%% Descrip.: Quote a string so that it can be included safely in a
-%%           MySQL query.
-%% Returns : Quoted = string()
-%%--------------------------------------------------------------------
-quote(String) when is_list(String) ->
-    [34 | lists:reverse([34 | quote(String, [])])].    %% 34 is $"
-
-quote([], Acc) ->
-    Acc;
-quote([0 | Rest], Acc) ->
-    quote(Rest, [$0, $\\ | Acc]);
-quote([10 | Rest], Acc) ->
-    quote(Rest, [$n, $\\ | Acc]);
-quote([13 | Rest], Acc) ->
-    quote(Rest, [$r, $\\ | Acc]);
-quote([$\\ | Rest], Acc) ->
-    quote(Rest, [$\\ , $\\ | Acc]);
-quote([39 | Rest], Acc) ->             %% 39 is $'
-    quote(Rest, [39, $\\ | Acc]);      %% 39 is $'
-quote([34 | Rest], Acc) ->             %% 34 is $"
-    quote(Rest, [34, $\\ | Acc]);      %% 34 is $"
-quote([26 | Rest], Acc) ->
-    quote(Rest, [$Z, $\\ | Acc]);
-quote([C | Rest], Acc) ->
-    quote(Rest, [C | Acc]).
-
-%%--------------------------------------------------------------------
-%% Function: asciz_binary(Data, Acc)
-%%           Data = binary()
-%%           Acc  = list(), input accumulator
-%% Descrip.: Find the first zero-byte in Data and add everything
-%%           before it to Acc, as a string.
-%% Returns : {NewList, Rest}
-%%           NewList = list(), Acc plus what we extracted from Data
-%%           Rest    = binary(), whatever was left of Data, not
-%%                     including the zero-byte
-%%--------------------------------------------------------------------
-asciz_binary(<<>>, Acc) ->
-    {lists:reverse(Acc), <<>>};
-asciz_binary(<<0:8, Rest/binary>>, Acc) ->
-    {lists:reverse(Acc), Rest};
-asciz_binary(<<C:8, Rest/binary>>, Acc) ->
-    asciz_binary(Rest, [C | Acc]).
-
-%%--------------------------------------------------------------------
-%% Function: connect(Id, Host, Port, User, Password, Database,
-%%                   Reconnect)
-%%           Id        = term(), connection-group Id
-%%           Host      = string()
-%%           Port      = undefined | integer()
-%%           User      = string()
-%%           Password  = string()
-%%           Database  = string()
-%%           Reconnect = true | false
-%% Descrip.: Starts a MySQL connection and, if successfull, registers
-%%           it with the mysql_dispatcher.
-%% Returns : {ok, ConnPid} | {error, Reason}
-%%--------------------------------------------------------------------
-connect(Id, Host, undefined, User, Password, Database, Reconnect) ->
-    connect(Id, Host, ?PORT, User, Password, Database, Reconnect);
-connect(Id, Host, Port, User, Password, Database, Reconnect) ->
-    {ok, LogFun} = gen_server:call(?SERVER, get_logfun),
-    case mysql_conn:start(Host, Port, User, Password, Database, LogFun) of
-       {ok, ConnPid} ->
-           MysqlConn =
-               case Reconnect of
-                   true ->
-                       #mysql_connection{id        = Id,
-                                         conn_pid  = ConnPid,
-                                         reconnect = true,
-                                         host      = Host,
-                                         port      = Port,
-                                         user      = User,
-                                         password  = Password,
-                                         database  = Database
-                                        };
-                   false ->
-                       #mysql_connection{id        = Id,
-                                         conn_pid  = ConnPid,
-                                         reconnect = false
-                                        }
-               end,
-           case gen_server:call(?SERVER, {add_mysql_connection, MysqlConn}) of
-               ok ->
-                   {ok, ConnPid};
-               Res ->
-                   Res
-           end;
-       {error, Reason} ->
-           {error, Reason}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: log(LogFun, Level, Format)
-%%           log(LogFun, Level, Format, Arguments)
-%%           LogFun    = undefined | function() with arity 3
-%%           Level     = debug | normal | error
-%%           Format    = string()
-%%           Arguments = list() of term()
-%% Descrip.: Either call the function LogFun with the Level, Format
-%%           and Arguments as parameters or log it to the console if
-%%           LogFun is undefined.
-%% Returns : void()
-%%
-%% Note    : Exported only for use by the mysql_* modules.
-%%
-%%--------------------------------------------------------------------
-log(LogFun, Level, Format) ->
-    log(LogFun, Level, Format, []).
-
-log(LogFun, Level, Format, Arguments) when is_function(LogFun) ->
-    LogFun(Level, Format, Arguments);
-log(undefined, _Level, Format, Arguments) ->
-    %% default is to log to console
-    io:format(Format, Arguments),
-    io:format("~n", []).
-
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Args) -> {ok, State} |
-%%                         {ok, State, Timeout} |
-%%                         ignore               |
-%%                         {stop, Reason}
-%%           Args = [Id, Host, Port, User, Password, Database, LogFun]
-%%             Id       = term(), connection-group Id
-%%             Host     = string()
-%%             Port     = integer()
-%%             User     = string()
-%%             Password = string()
-%%             Database = string()
-%%             LogFun   = undefined | function() with arity 3
-%% Descrip.: Initiates the gen_server (MySQL dispatcher).
-%%--------------------------------------------------------------------
-init([Id, Host, Port, User, Password, Database, LogFun]) ->
-    case mysql_conn:start(Host, Port, User, Password, Database, LogFun) of
-       {ok, ConnPid} ->
-           MysqlConn = #mysql_connection{id        = Id,
-                                         conn_pid  = ConnPid,
-                                         reconnect = true,
-                                         host      = Host,
-                                         port      = Port,
-                                         user      = User,
-                                         password  = Password,
-                                         database  = Database
-                                        },
-           case add_mysql_conn(MysqlConn, []) of
-               {ok, ConnList} ->
-                   {ok, #state{log_fun    = LogFun,
-                               conn_list = ConnList,
-                gc_tref = undefined
-                              }};
-               error ->
-                   Msg = "mysql: Failed adding first MySQL connection handler to my list, exiting",
-                   log(LogFun, error, Msg),
-                   {error, Msg}
-           end;
-       {error, Reason} ->
-           log(LogFun, error, "mysql: Failed starting first MySQL connection handler, exiting"),
-           {stop, {error, Reason}}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: handle_call(Msg, From, State)
-%% Descrip.: Handling call messages.
-%% Returns : {reply, Reply, State}          |
-%%           {reply, Reply, State, Timeout} |
-%%           {noreply, State}               |
-%%           {noreply, State, Timeout}      |
-%%           {stop, Reason, Reply, State}   | (terminate/2 is called)
-%%           {stop, Reason, State}            (terminate/2 is called)
-%%--------------------------------------------------------------------
-
-
-%%--------------------------------------------------------------------
-%% Function: handle_call({fetch, Id, Query}, From, State)
-%%           Id    = term(), connection-group id
-%%           Query = string(), MySQL query
-%% Descrip.: Make a MySQL query. Use the first connection matching Id
-%%           in our connection-list. Don't block the mysql_dispatcher
-%%           by returning {noreply, ...} here and let the mysql_conn
-%%           do gen_server:reply(...) when it has an answer.
-%% Returns : {noreply, NewState}             |
-%%           {reply, {error, Reason}, State}
-%%           NewState = state record()
-%%           Reason   = atom() | string()
-%%--------------------------------------------------------------------
-handle_call({fetch, Id, Query}, From, State) ->
-    log(State#state.log_fun, debug, "mysql: fetch ~p (id ~p)", [Query, Id]),
-    case get_next_mysql_connection_for_id(Id, State#state.conn_list) of
-       {ok, MysqlConn, RestOfConnList} when is_record(MysqlConn, mysql_connection) ->
-           mysql_conn:fetch(MysqlConn#mysql_connection.conn_pid, Query, From),
-           %% move this mysql socket to the back of the list
-           NewConnList = RestOfConnList ++ [MysqlConn],
-           %% The ConnPid process does a gen_server:reply() when it has an answer
-           {noreply, State#state{conn_list = NewConnList}};
-       nomatch ->
-           %% we have no active connection matching Id
-           {reply, {error, no_connection}, State}
-    end;
-
-%%--------------------------------------------------------------------
-%% Function: handle_call({add_mysql_connection, Conn}, From, State)
-%%           Conn = mysql_connection record()
-%% Descrip.: Add Conn to our list of connections.
-%% Returns : {reply, Reply, NewState}
-%%           Reply = ok | {error, Reason}
-%%           NewState = state record()
-%%           Reason   = string()
-%%--------------------------------------------------------------------
-handle_call({add_mysql_connection, Conn}, _From, State) when is_record(Conn, mysql_connection) ->
-    case add_mysql_conn(Conn, State#state.conn_list) of
-       {ok, NewConnList} ->
-           {Id, ConnPid} = {Conn#mysql_connection.id, Conn#mysql_connection.conn_pid},
-           log(State#state.log_fun, normal, "mysql: Added connection with id '~p' (pid ~p) to my list",
-               [Id, ConnPid]),
-           {reply, ok, State#state{conn_list = NewConnList}};
-       error ->
-           {reply, {error, "failed adding MySQL connection to my list"}, State}
-    end;
-
-%%--------------------------------------------------------------------
-%% Function: handle_call(get_logfun, From, State)
-%% Descrip.: Fetch our logfun.
-%% Returns : {reply, {ok, LogFun}, State}
-%%           LogFun = undefined | function() with arity 3
-%%--------------------------------------------------------------------
-handle_call(get_logfun, _From, State) ->
-    {reply, {ok, State#state.log_fun}, State};
-
-handle_call(stop, _From, State) ->
-    {stop, normal, State};
-
-handle_call({gc_each, Millisec}, _From, State) ->
-    case State#state.gc_tref of
-        undefined -> ok;
-        TRef ->
-            timer:cancel(TRef)
-    end,
-    case timer:send_interval(Millisec, gc) of
-        {ok, NewTRef} ->
-            {reply, ok, State#state{gc_tref = NewTRef}};
-        {error, Reason} ->
-            {reply, {error, Reason}, State}
-    end;
-
-handle_call(Unknown, _From, State) ->
-    log(State#state.log_fun, error, "mysql: Received unknown gen_server call : ~p", [Unknown]),
-    {reply, {error, "unknown gen_server call in mysql client"}, State}.
-
-
-%%--------------------------------------------------------------------
-%% Function: handle_cast(Msg, State)
-%% Descrip.: Handling cast messages
-%% Returns : {noreply, State}          |
-%%           {noreply, State, Timeout} |
-%%           {stop, Reason, State}            (terminate/2 is called)
-%%--------------------------------------------------------------------
-handle_cast(Unknown, State) ->
-    log(State#state.log_fun, error, "mysql: Received unknown gen_server cast : ~p", [Unknown]),
-    {noreply, State}.
-
-
-%%--------------------------------------------------------------------
-%% Function: handle_info(Msg, State)
-%% Descrip.: Handling all non call/cast messages
-%% Returns : {noreply, State}          |
-%%           {noreply, State, Timeout} |
-%%           {stop, Reason, State}            (terminate/2 is called)
-%%--------------------------------------------------------------------
-
-%%--------------------------------------------------------------------
-%% Function: handle_info({'DOWN', ...}, State)
-%% Descrip.: Handle a message that one of our monitored processes
-%%           (mysql_conn processes in our connection list) has exited.
-%%           Remove the entry from our list.
-%% Returns : {noreply, NewState}   |
-%%           {stop, normal, State}
-%%           NewState = state record()
-%%
-%% Note    : For now, we stop if our connection list becomes empty.
-%%           We should try to reconnect for a while first, to not
-%%           eventually stop the whole OTP application if the MySQL-
-%%           server is shut down and the mysql_dispatcher was super-
-%%           vised by an OTP supervisor.
-%%--------------------------------------------------------------------
-handle_info({'DOWN', _MonitorRef, process, Pid, Info}, State) ->
-    LogFun = State#state.log_fun,
-    case remove_mysql_connection_using_pid(Pid, State#state.conn_list, []) of
-       {ok, Conn, NewConnList} ->
-           LogLevel = case Info of
-                          normal -> normal;
-                          _ -> error
-                      end,
-           log(LogFun, LogLevel, "mysql: MySQL connection pid ~p exited : ~p", [Pid, Info]),
-           log(LogFun, normal, "mysql: Removed MySQL connection with pid ~p from list",
-               [Pid]),
-           case Conn#mysql_connection.reconnect of
-               true ->
-                   start_reconnect(Conn, LogFun);
-               false ->
-                   ok
-           end,
-           {noreply, State#state{conn_list = NewConnList}};
-       nomatch ->
-           log(LogFun, error, "mysql: Received 'DOWN' signal from pid ~p not in my list", [Pid]),
-           {noreply, State}
-    end;
-
-handle_info(gc, #state{conn_list = Connections} = State) ->
-    [erlang:garbage_collect(C#mysql_connection.conn_pid) || C <- Connections],
-    erlang:garbage_collect(self()),
-    {noreply, State};
-
-
-handle_info(Info, State) ->
-    log(State#state.log_fun, error, "mysql: Received unknown signal : ~p", [Info]),
-    {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% Function: terminate(Reason, State)
-%% Descrip.: Shutdown the server
-%% Returns : Reason
-%%--------------------------------------------------------------------
-terminate(Reason, State) ->
-    LogFun = State#state.log_fun,
-    LogLevel = case Reason of
-                  normal -> debug;
-                  _ -> error
-              end,
-    log(LogFun, LogLevel, "mysql: Terminating with reason : ~p", [Reason]),
-    lists:foreach(fun(MysqlConn) ->
-                         MysqlConn#mysql_connection.conn_pid ! close
-                 end, State#state.conn_list),
-    Reason.
-
-%%--------------------------------------------------------------------
-%% Function: code_change(_OldVsn, State, _Extra)
-%% Descrip.: Convert process state when code is changed
-%% Returns : {ok, State}
-%%--------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
-    {ok, State}.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: add_mysql_conn(Conn, ConnList)
-%%           Conn     = mysql_connection record()
-%%           ConnList = list() of mysql_connection record()
-%% Descrip.: Set up process monitoring of the mysql_conn process and
-%%           then add it (first) to ConnList.
-%% Returns : NewConnList = list() of mysql_connection record()
-%%--------------------------------------------------------------------
-add_mysql_conn(Conn, ConnList) when is_record(Conn, mysql_connection), is_list(ConnList) ->
-    erlang:monitor(process, Conn#mysql_connection.conn_pid),
-    {ok, [Conn | ConnList]}.
-
-%%--------------------------------------------------------------------
-%% Function: remove_mysql_connection_using_pid(Pid, ConnList)
-%%           Pid      = pid()
-%%           ConnList = list() of mysql_connection record()
-%% Descrip.: Removes the first mysql_connection in ConnList that has
-%%           a pid matching Pid.
-%% Returns : {ok, Conn, NewConnList} | nomatch
-%%           Conn        = mysql_connection record()
-%%           NewConnList = list() of mysql_connection record()
-%%--------------------------------------------------------------------
-remove_mysql_connection_using_pid(Pid, [#mysql_connection{conn_pid = Pid} = H | T], Res) ->
-    {ok, H, lists:reverse(Res) ++ T};
-remove_mysql_connection_using_pid(Pid, [H | T], Res) when is_record(H, mysql_connection) ->
-    remove_mysql_connection_using_pid(Pid, T, [H | Res]);
-remove_mysql_connection_using_pid(_Pid, [], _Res) ->
-    nomatch.
-
-%%--------------------------------------------------------------------
-%% Function: get_next_mysql_connection_for_id(Id, ConnList)
-%%           Id       = term(), connection-group id
-%%           ConnList = list() of mysql_connection record()
-%% Descrip.: Find the first mysql_connection in ConnList that has an
-%%           id matching Id.
-%% Returns : {ok, Conn, NewConnList} | nomatch
-%%           Conn        = mysql_connection record()
-%%           NewConnList = list() of mysql_connection record(), same
-%%                         as ConnList but without Conn
-%%--------------------------------------------------------------------
-get_next_mysql_connection_for_id(Id, ConnList) ->
-    get_next_mysql_connection_for_id(Id, ConnList, []).
-
-get_next_mysql_connection_for_id(Id, [#mysql_connection{id = Id} = H | T], Res) ->
-    {ok, H, lists:reverse(Res) ++ T};
-get_next_mysql_connection_for_id(Id, [H | T], Res) when is_record(H, mysql_connection) ->
-    get_next_mysql_connection_for_id(Id, T, [H | Res]);
-get_next_mysql_connection_for_id(_Id, [], _Res) ->
-    nomatch.
-
-%%--------------------------------------------------------------------
-%% Function: start_reconnect(Conn, LogFun)
-%%           Conn   = mysql_connection record()
-%%           LogFun = undefined | function() with arity 3
-%% Descrip.: Spawns a process that will try to re-establish a new
-%%           connection instead of the one in Conn which has just
-%%           died.
-%% Returns : ok
-%%--------------------------------------------------------------------
-start_reconnect(Conn, LogFun) when is_record(Conn, mysql_connection) ->
-    Pid = spawn(fun () ->
-                       reconnect_loop(Conn#mysql_connection{conn_pid = undefined}, LogFun, 0)
-               end),
-    {Id, Host, Port} = {Conn#mysql_connection.id, Conn#mysql_connection.host, Conn#mysql_connection.port},
-    log(LogFun, debug, "mysql: Started pid ~p to try and reconnect to ~p:~s:~p (replacing "
-       "connection with pid ~p)", [Pid, Id, Host, Port, Conn#mysql_connection.conn_pid]),
-    ok.
-
-%%--------------------------------------------------------------------
-%% Function: reconnect_loop(Conn, LogFun, 0)
-%%           Conn   = mysql_connection record()
-%%           LogFun = undefined | function() with arity 3
-%% Descrip.: Loop indefinately until we are able to reconnect to the
-%%           server specified in the now dead connection Conn.
-%% Returns : ok
-%%--------------------------------------------------------------------
-reconnect_loop(Conn, LogFun, N) when is_record(Conn, mysql_connection) ->
-    {Id, Host, Port} = {Conn#mysql_connection.id, Conn#mysql_connection.host, Conn#mysql_connection.port},
-    case connect(Id,
-                Host,
-                Port,
-                Conn#mysql_connection.user,
-                Conn#mysql_connection.password,
-                Conn#mysql_connection.database,
-                Conn#mysql_connection.reconnect) of
-       {ok, ConnPid} ->
-           log(LogFun, debug, "mysql_reconnect: Managed to reconnect to ~p:~s:~p (connection pid ~p)",
-               [Id, Host, Port, ConnPid]),
-           ok;
-       {error, Reason} ->
-           %% log every once in a while
-           NewN = case N of
-                      10 ->
-                          log(LogFun, debug, "mysql_reconnect: Still unable to connect to ~p:~s:~p (~p)",
-                              [Id, Host, Port, Reason]),
-                          0;
-                      _ ->
-                          N + 1
-                  end,
-           %% sleep between every unsuccessfull attempt
-           timer:sleep(20 * 1000),
-           reconnect_loop(Conn, LogFun, NewN)
-    end.
diff --git a/src/mysql/mysql.hrl b/src/mysql/mysql.hrl
deleted file mode 100644 (file)
index aee5611..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-%% MySQL result record:
--record(mysql_result,
-       {fieldinfo=[],
-        rows=[],
-        affectedrows=0,
-        error=""}).
diff --git a/src/mysql/mysql_auth.erl b/src/mysql/mysql_auth.erl
deleted file mode 100644 (file)
index 3e4b962..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : mysql_auth.erl
-%%% Author  : Fredrik Thulin <ft@it.su.se>
-%%% Descrip.: MySQL client authentication functions.
-%%% Created :  4 Aug 2005 by Fredrik Thulin <ft@it.su.se>
-%%%
-%%% Note    : All MySQL code was written by Magnus Ahltorp, originally
-%%%           in the file mysql.erl - I just moved it here.
-%%%
-%%% Copyright (c) 2001-2004 Kungliga Tekniska Högskolan
-%%% See the file COPYING
-%%%
-%%%-------------------------------------------------------------------
--module(mysql_auth).
-
-%%--------------------------------------------------------------------
-%% External exports (should only be used by the 'mysql_conn' module)
-%%--------------------------------------------------------------------
--export([
-        do_old_auth/7,
-        do_new_auth/8
-       ]).
-
-%%--------------------------------------------------------------------
-%% Macros
-%%--------------------------------------------------------------------
--define(LONG_PASSWORD, 1).
--define(FOUND_ROWS, 2).
--define(LONG_FLAG, 4).
--define(PROTOCOL_41, 512).
--define(TRANSACTIONS, 8192).
--define(SECURE_CONNECTION, 32768).
--define(CONNECT_WITH_DB, 8).
-
--define(MAX_PACKET_SIZE, 1000000).
-
-%%====================================================================
-%% External functions
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: do_old_auth(Sock, RecvPid, SeqNum, User, Password, Salt1,
-%%                       LogFun)
-%%           Sock     = term(), gen_tcp socket
-%%           RecvPid  = pid(), receiver process pid
-%%           SeqNum   = integer(), first sequence number we should use
-%%           User     = string(), MySQL username
-%%           Password = string(), MySQL password
-%%           Salt1    = string(), salt 1 from server greeting
-%%           LogFun   = undefined | function() of arity 3
-%% Descrip.: Perform old-style MySQL authentication.
-%% Returns : result of mysql_conn:do_recv/3
-%%--------------------------------------------------------------------
-do_old_auth(Sock, RecvPid, SeqNum, User, Password, Salt1, LogFun) ->
-    Auth = password_old(Password, Salt1),
-    Packet2 = make_auth(User, Auth),
-    do_send(Sock, Packet2, SeqNum, LogFun),
-    mysql_conn:do_recv(LogFun, RecvPid, SeqNum).
-
-%%--------------------------------------------------------------------
-%% Function: do_new_auth(Sock, RecvPid, SeqNum, User, Password, Salt1,
-%%                       Salt2, LogFun)
-%%           Sock     = term(), gen_tcp socket
-%%           RecvPid  = pid(), receiver process pid
-%%           SeqNum   = integer(), first sequence number we should use
-%%           User     = string(), MySQL username
-%%           Password = string(), MySQL password
-%%           Salt1    = string(), salt 1 from server greeting
-%%           Salt2    = string(), salt 2 from server greeting
-%%           LogFun   = undefined | function() of arity 3
-%% Descrip.: Perform MySQL authentication.
-%% Returns : result of mysql_conn:do_recv/3
-%%--------------------------------------------------------------------
-do_new_auth(Sock, RecvPid, SeqNum, User, Password, Salt1, Salt2, LogFun) ->
-    Auth = password_new(Password, Salt1 ++ Salt2),
-    Packet2 = make_new_auth(User, Auth, none),
-    do_send(Sock, Packet2, SeqNum, LogFun),
-    case mysql_conn:do_recv(LogFun, RecvPid, SeqNum) of
-       {ok, Packet3, SeqNum2} ->
-           case Packet3 of
-               <<254:8>> ->
-                   AuthOld = password_old(Password, Salt1),
-                   do_send(Sock, <<AuthOld/binary, 0:8>>, SeqNum2 + 1, LogFun),
-                   mysql_conn:do_recv(LogFun, RecvPid, SeqNum2 + 1);
-               _ ->
-                   {ok, Packet3, SeqNum2}
-           end;
-       {error, Reason} ->
-           {error, Reason}
-    end.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-
-password_old(Password, Salt) ->
-    {P1, P2} = hash(Password),
-    {S1, S2} = hash(Salt),
-    Seed1 = P1 bxor S1,
-    Seed2 = P2 bxor S2,
-    List = rnd(9, Seed1, Seed2),
-    {L, [Extra]} = lists:split(8, List),
-    list_to_binary(lists:map(fun (E) ->
-                                    E bxor (Extra - 64)
-                            end, L)).
-
-%% part of do_old_auth/4, which is part of mysql_init/4
-make_auth(User, Password) ->
-    Caps = ?LONG_PASSWORD bor ?LONG_FLAG
-       bor ?TRANSACTIONS bor ?FOUND_ROWS,
-    Maxsize = 0,
-    UserB = list_to_binary(User),
-    PasswordB = Password,
-    <<Caps:16/little, Maxsize:24/little, UserB/binary, 0:8,
-    PasswordB/binary>>.
-
-%% part of do_new_auth/4, which is part of mysql_init/4
-make_new_auth(User, Password, Database) ->
-    DBCaps = case Database of
-                none ->
-                    0;
-                _ ->
-                    ?CONNECT_WITH_DB
-            end,
-    Caps = ?LONG_PASSWORD bor ?LONG_FLAG bor ?TRANSACTIONS bor
-       ?PROTOCOL_41 bor ?SECURE_CONNECTION bor DBCaps
-       bor ?FOUND_ROWS,
-    Maxsize = ?MAX_PACKET_SIZE,
-    UserB = list_to_binary(User),
-    PasswordL = size(Password),
-    DatabaseB = case Database of
-                   none ->
-                       <<>>;
-                   _ ->
-                       list_to_binary(Database)
-               end,
-    <<Caps:32/little, Maxsize:32/little, 8:8, 0:23/integer-unit:8,
-    UserB/binary, 0:8, PasswordL:8, Password/binary, DatabaseB/binary>>.
-
-hash(S) ->
-    hash(S, 1345345333, 305419889, 7).
-
-hash([C | S], N1, N2, Add) ->
-    N1_1 = N1 bxor (((N1 band 63) + Add) * C + N1 * 256),
-    N2_1 = N2 + ((N2 * 256) bxor N1_1),
-    Add_1 = Add + C,
-    hash(S, N1_1, N2_1, Add_1);
-hash([], N1, N2, _Add) ->
-    Mask = (1 bsl 31) - 1,
-    {N1 band Mask , N2 band Mask}.
-
-rnd(N, Seed1, Seed2) ->
-    Mod = (1 bsl 30) - 1,
-    rnd(N, [], Seed1 rem Mod, Seed2 rem Mod).
-
-rnd(0, List, _, _) ->
-    lists:reverse(List);
-rnd(N, List, Seed1, Seed2) ->
-    Mod = (1 bsl 30) - 1,
-    NSeed1 = (Seed1 * 3 + Seed2) rem Mod,
-    NSeed2 = (NSeed1 + Seed2 + 33) rem Mod,
-    Float = (float(NSeed1) / float(Mod))*31,
-    Val = trunc(Float)+64,
-    rnd(N - 1, [Val | List], NSeed1, NSeed2).
-
-
-
-dualmap(_F, [], []) ->
-    [];
-dualmap(F, [E1 | R1], [E2 | R2]) ->
-    [F(E1, E2) | dualmap(F, R1, R2)].
-
-bxor_binary(B1, B2) ->
-    list_to_binary(dualmap(fun (E1, E2) ->
-                                  E1 bxor E2
-                          end, binary_to_list(B1), binary_to_list(B2))).
-
-password_new(Password, Salt) ->
-    Stage1 = crypto:sha(Password),
-    Stage2 = crypto:sha(Stage1),
-    Res = crypto:sha_final(
-           crypto:sha_update(
-             crypto:sha_update(crypto:sha_init(), Salt),
-             Stage2)
-          ),
-    bxor_binary(Res, Stage1).
-
-
-do_send(Sock, Packet, Num, LogFun) ->
-    mysql:log(LogFun, debug, "mysql_auth send packet ~p: ~p", [Num, Packet]),
-    Data = <<(size(Packet)):24/little, Num:8, Packet/binary>>,
-    gen_tcp:send(Sock, Data).
diff --git a/src/mysql/mysql_conn.erl b/src/mysql/mysql_conn.erl
deleted file mode 100644 (file)
index cecd447..0000000
+++ /dev/null
@@ -1,759 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : mysql_conn.erl
-%%% Author  : Fredrik Thulin <ft@it.su.se>
-%%% Descrip.: MySQL connection handler, handles de-framing of messages
-%%%           received by the MySQL receiver process.
-%%% Created :  5 Aug 2005 by Fredrik Thulin <ft@it.su.se>
-%%% Modified: 11 Jan 2006 by Mickael Remond <mickael.remond@process-one.net>
-%%%
-%%% Note    : All MySQL code was written by Magnus Ahltorp, originally
-%%%           in the file mysql.erl - I just moved it here.
-%%%
-%%% Copyright (c) 2001-2004 Kungliga Tekniska Högskolan
-%%% See the file COPYING
-%%%
-%%%
-%%% This module handles a single connection to a single MySQL server.
-%%% You can use it stand-alone, or through the 'mysql' module if you
-%%% want to have more than one connection to the server, or
-%%% connections to different servers.
-%%%
-%%% To use it stand-alone, set up the connection with
-%%%
-%%%   {ok, Pid} = mysql_conn:start(Host, Port, User, Password,
-%%%                                Database, LogFun)
-%%%
-%%%         Host     = string()
-%%%         Port     = integer()
-%%%         User     = string()
-%%%         Password = string()
-%%%         Database = string()
-%%%         LogFun   = undefined | (gives logging to console)
-%%%                    function() of arity 3 (Level, Fmt, Args)
-%%%
-%%% Note: In stand-alone mode you have to start Erlang crypto application by
-%%% yourself with crypto:start()
-%%%
-%%% and then make MySQL querys with
-%%%
-%%%   Result = mysql_conn:fetch(Pid, Query, self())
-%%%
-%%%         Result = {data, MySQLRes}    |
-%%%                  {updated, MySQLRes} |
-%%%                  {error, MySQLRes}
-%%%          Where: MySQLRes = #mysql_result
-%%%
-%%% Actual data can be extracted from MySQLRes by calling the following API
-%%% functions:
-%%%     - on data received:
-%%%          FieldInfo = mysql:get_result_field_info(MysqlRes)
-%%%          AllRows   = mysql:get_result_rows(MysqlRes)
-%%%         with FieldInfo = list() of {Table, Field, Length, Name}
-%%%          and AllRows = list() of list() representing records
-%%%     - on update:
-%%%          Affected= mysql:get_result_affected_rows(MysqlRes)
-%%%         with Affected = integer()
-%%%     - on error:
-%%%          Reason    = mysql:get_result_reason(MysqlRes)
-%%%         with Reason = string()
-%%%-------------------------------------------------------------------
-
--module(mysql_conn).
-
-%%--------------------------------------------------------------------
-%% External exports
-%%--------------------------------------------------------------------
--export([start/6,
-        start_link/6,
-        fetch/3,
-        fetch/4,
-        squery/4,
-        stop/1
-       ]).
-
-%%--------------------------------------------------------------------
-%% External exports (should only be used by the 'mysql_auth' module)
-%%--------------------------------------------------------------------
--export([do_recv/3
-       ]).
-
--include("mysql.hrl").
--record(state, {
-         mysql_version,
-         log_fun,
-         recv_pid,
-         socket,
-         data
-        }).
-
--define(SECURE_CONNECTION, 32768).
--define(MYSQL_QUERY_OP, 3).
--define(DEFAULT_STANDALONE_TIMEOUT, 5000).
--define(DEFAULT_RESULT_TYPE, list).
--define(MYSQL_4_0, 40). %% Support for MySQL 4.0.x
--define(MYSQL_4_1, 41). %% Support for MySQL 4.1.x et 5.0.x
-
-%%====================================================================
-%% External functions
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: start(Host, Port, User, Password, Database, LogFun)
-%% Function: start_link(Host, Port, User, Password, Database, LogFun)
-%%           Host     = string()
-%%           Port     = integer()
-%%           User     = string()
-%%           Password = string()
-%%           Database = string()
-%%           LogFun   = undefined | function() of arity 3
-%% Descrip.: Starts a mysql_conn process that connects to a MySQL
-%%           server, logs in and chooses a database.
-%% Returns : {ok, Pid} | {error, Reason}
-%%           Pid    = pid()
-%%           Reason = string()
-%%--------------------------------------------------------------------
-start(Host, Port, User, Password,
-      Database, LogFun) when is_list(Host),
-                            is_integer(Port),
-                            is_list(User),
-                            is_list(Password),
-                            is_list(Database) ->
-    ConnPid = self(),
-    Pid = spawn(fun () ->
-                       init(Host, Port, User, Password, Database,
-                            LogFun, ConnPid)
-               end),
-    post_start(Pid, LogFun).
-
-start_link(Host, Port, User, Password,
-          Database, LogFun) when is_list(Host),
-                                 is_integer(Port),
-                                 is_list(User),
-                                 is_list(Password),
-                                 is_list(Database) ->
-    ConnPid = self(),
-    Pid = spawn_link(fun () ->
-                       init(Host, Port, User, Password, Database,
-                            LogFun, ConnPid)
-               end),
-    post_start(Pid, LogFun).
-
-%% part of start/6 or start_link/6:
-post_start(Pid, _LogFun) ->
-    %%Timeout = get_option(timeout, Options, ?DEFAULT_STANDALONE_TIMEOUT),
-    %%TODO find a way to get configured Options here
-    Timeout= ?DEFAULT_STANDALONE_TIMEOUT,
-    receive
-       {mysql_conn, Pid, ok} ->
-           {ok, Pid};
-       {mysql_conn, Pid, {error, Reason}} ->
-           mysql:log(_LogFun, error, "mysql_conn: post_start error ~p~n",
-                     [Reason]),
-           stop(Pid),
-           {error, Reason}
-%      Unknown ->
-%          mysql:log(_LogFun, error, "mysql_conn: Received unknown signal, exiting"),
-%          mysql:log(_LogFun, debug, "mysql_conn: Unknown signal : ~p", [Unknown]),
-%          {error, "unknown signal received"}
-    after Timeout ->
-           mysql:log(_LogFun, error, "mysql_conn: post_start timeout~n",
-                     []),
-           stop(Pid),
-           {error, "timed out"}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: fetch(Pid, Query, From)
-%%           fetch(Pid, Query, From, Timeout)
-%%           Pid     = pid(), mysql_conn to send fetch-request to
-%%           Query   = string(), MySQL query in verbatim
-%%           From    = pid() or term(), use a From of self() when
-%%                     using this module for a single connection,
-%%                     or pass the gen_server:call/3 From argument if
-%%                     using a gen_server to do the querys (e.g. the
-%%                     mysql_dispatcher)
-%%           Timeout = integer() | infinity, gen_server timeout value
-%% Descrip.: Send a query and wait for the result if running stand-
-%%           alone (From = self()), but don't block the caller if we
-%%           are not running stand-alone (From = gen_server From).
-%% Returns : ok                        | (non-stand-alone mode)
-%%           {data, #mysql_result}     | (stand-alone mode)
-%%           {updated, #mysql_result}  | (stand-alone mode)
-%%           {error, #mysql_result}      (stand-alone mode)
-%%           FieldInfo = term()
-%%           Rows      = list() of [string()]
-%%           Reason    = term()
-%%--------------------------------------------------------------------
-
-fetch(Pid, Query, From) ->
-    squery(Pid, Query, From, []).
-fetch(Pid, Query, From, Timeout) ->
-    squery(Pid, Query, From, [{timeout, Timeout}]).
-
-squery(Pid, Query, From, Options) when is_pid(Pid), is_list(Query) ->
-    Self = self(),
-    Timeout = get_option(timeout, Options, ?DEFAULT_STANDALONE_TIMEOUT),
-    TRef = erlang:start_timer(Timeout, self(), timeout),
-    Pid ! {fetch, TRef, Query, From, Options},
-    case From of
-       Self ->
-           %% We are not using a mysql_dispatcher, await the response
-           wait_fetch_result(TRef, Pid);
-       _ ->
-           %% From is gen_server From, Pid will do gen_server:reply()
-           %% when it has an answer
-           ok
-    end.
-
-wait_fetch_result(TRef, Pid) ->
-    receive
-       {fetch_result, TRef, Pid, Result} ->
-           case erlang:cancel_timer(TRef) of
-               false ->
-                   receive
-                       {timeout, TRef, _} ->
-                           ok
-                   after 0 ->
-                           ok
-                   end;
-               _ ->
-                   ok
-           end,
-           Result;
-       {fetch_result, _BadRef, Pid, _Result} ->
-           wait_fetch_result(TRef, Pid);
-       {timeout, TRef, _Info} ->
-           stop(Pid),
-           {error, "query timed out"}
-    end.
-
-stop(Pid) ->
-    Pid ! close.
-
-
-%%--------------------------------------------------------------------
-%% Function: do_recv(LogFun, RecvPid, SeqNum)
-%%           LogFun  = undefined | function() with arity 3
-%%           RecvPid = pid(), mysql_recv process
-%%           SeqNum  = undefined | integer()
-%% Descrip.: Wait for a frame decoded and sent to us by RecvPid.
-%%           Either wait for a specific frame if SeqNum is an integer,
-%%           or just any frame if SeqNum is undefined.
-%% Returns : {ok, Packet, Num} |
-%%           {error, Reason}
-%%           Reason = term()
-%%
-%% Note    : Only to be used externally by the 'mysql_auth' module.
-%%--------------------------------------------------------------------
-do_recv(LogFun, RecvPid, SeqNum) when is_function(LogFun);
-                                     LogFun == undefined,
-                                     SeqNum == undefined ->
-    receive
-        {mysql_recv, RecvPid, data, Packet, Num} ->
-            %%mysql:log(LogFun, debug, "mysql_conn: recv packet ~p:
-            %%~p", [Num, Packet]),
-           {ok, Packet, Num};
-       {mysql_recv, RecvPid, closed, _E} ->
-           mysql:log(LogFun, error, "mysql_conn: mysql_recv:"
-                     " socket was closed ~p~n", [{RecvPid, _E}]),
-           {error, "mysql_recv: socket was closed"}
-    end;
-do_recv(LogFun, RecvPid, SeqNum) when is_function(LogFun);
-                                     LogFun == undefined,
-                                     is_integer(SeqNum) ->
-    ResponseNum = SeqNum + 1,
-    receive
-        {mysql_recv, RecvPid, data, Packet, ResponseNum} ->
-            %%mysql:log(LogFun, debug, "mysql_conn: recv packet ~p:
-            %%~p", [ResponseNum, Packet]),
-           {ok, Packet, ResponseNum};
-       {mysql_recv, RecvPid, closed, _E} ->
-           mysql:log(LogFun, error, "mysql_conn: mysql_recv:"
-                     " socket was closed 2 ~p~n", [{RecvPid, _E}]),
-           {error, "mysql_recv: socket was closed"}
-        end.
-
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init(Host, Port, User, Password, Database, LogFun,
-%%                Parent)
-%%           Host     = string()
-%%           Port     = integer()
-%%           User     = string()
-%%           Password = string()
-%%           Database = string()
-%%           LogFun   = undefined | function() of arity 3
-%%           Parent   = pid() of process starting this mysql_conn
-%% Descrip.: Connect to a MySQL server, log in and chooses a database.
-%%           Report result of this to Parent, and then enter loop() if
-%%           we were successfull.
-%% Returns : void() | does not return
-%%--------------------------------------------------------------------
-init(Host, Port, User, Password, Database, LogFun, Parent) ->
-    case mysql_recv:start_link(Host, Port, LogFun, self()) of
-       {ok, RecvPid, Sock} ->
-           case mysql_init(Sock, RecvPid, User, Password, LogFun) of
-               {ok, Version} ->
-                   case do_query(Sock, RecvPid, LogFun, "use " ++ Database,
-                                 Version, [{result_type, binary}]) of
-                       {error, MySQLRes} ->
-                           mysql:log(LogFun, error,
-                                     "mysql_conn: Failed changing"
-                                     " to database ~p : ~p",
-                                     [Database,
-                                      mysql:get_result_reason(MySQLRes)]),
-                           gen_tcp:close(Sock),
-                           Parent ! {mysql_conn, self(),
-                                     {error, failed_changing_database}};
-                       %% ResultType: data | updated
-                       {_ResultType, _MySQLRes} ->
-                           Parent ! {mysql_conn, self(), ok},
-                           State = #state{mysql_version=Version,
-                                          recv_pid = RecvPid,
-                                          socket   = Sock,
-                                          log_fun  = LogFun,
-                                          data     = <<>>
-                                         },
-                           loop(State)
-                   end;
-               {error, _Reason} ->
-                   Parent ! {mysql_conn, self(), {error, login_failed}}
-           end;
-       E ->
-           mysql:log(LogFun, error, "mysql_conn: "
-                     "Failed connecting to ~p:~p : ~p",
-                     [Host, Port, E]),
-           Parent ! {mysql_conn, self(), {error, connect_failed}}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: loop(State)
-%%           State = state record()
-%% Descrip.: Wait for signals asking us to perform a MySQL query, or
-%%           signals that the socket was closed.
-%% Returns : error | does not return
-%%--------------------------------------------------------------------
-loop(State) ->
-    RecvPid = State#state.recv_pid,
-    receive
-       {fetch, Ref, Query, GenSrvFrom, Options} ->
-           %% GenSrvFrom is either a gen_server:call/3 From term(),
-           %% or a pid if no gen_server was used to make the query
-           Res = do_query(State, Query, Options),
-           case is_pid(GenSrvFrom) of
-               true ->
-                   %% The query was not sent using gen_server mechanisms
-                   GenSrvFrom ! {fetch_result, Ref, self(), Res};
-               false ->
-                   %% the timer is canceled in wait_fetch_result/2, but we wait on that funtion only if the query
-                   %% was not sent using the mysql gen_server. So we at least should try to cancel the timer here
-                   %% (no warranty, the gen_server can still receive timeout messages)
-                   erlang:cancel_timer(Ref),
-                   gen_server:reply(GenSrvFrom, Res)
-           end,
-           loop(State);
-       {mysql_recv, RecvPid, data, Packet, Num} ->
-           mysql:log(State#state.log_fun, error, "mysql_conn: "
-                     "Received MySQL data when not expecting any "
-                     "(num ~p) - ignoring it", [Num]),
-           mysql:log(State#state.log_fun, error, "mysql_conn: "
-                     "Unexpected MySQL data (num ~p) :~n~p",
-                     [Num, Packet]),
-           loop(State);
-       close ->
-           mysql:log(State#state.log_fun, error, "mysql_conn: "
-                     "Received close signal, exiting.", []),
-           close_connection(State);
-        Unknown ->
-           mysql:log(State#state.log_fun, error, "mysql_conn: "
-                     "Received unknown signal, exiting : ~p",
-                     [Unknown]),
-           close_connection(State),
-           error
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: mysql_init(Sock, RecvPid, User, Password, LogFun)
-%%           Sock     = term(), gen_tcp socket
-%%           RecvPid  = pid(), mysql_recv process
-%%           User     = string()
-%%           Password = string()
-%%           LogFun   = undefined | function() with arity 3
-%% Descrip.: Try to authenticate on our new socket.
-%% Returns : ok | {error, Reason}
-%%           Reason = string()
-%%--------------------------------------------------------------------
-mysql_init(Sock, RecvPid, User, Password, LogFun) ->
-    case do_recv(LogFun, RecvPid, undefined) of
-       {ok, Packet, InitSeqNum} ->
-           {Version, Salt1, Salt2, Caps} = greeting(Packet, LogFun),
-           AuthRes =
-               case Caps band ?SECURE_CONNECTION of
-                   ?SECURE_CONNECTION ->
-                       mysql_auth:do_new_auth(Sock, RecvPid,
-                                              InitSeqNum + 1,
-                                              User, Password,
-                                              Salt1, Salt2, LogFun);
-                   _ ->
-                       mysql_auth:do_old_auth(Sock, RecvPid,
-                                              InitSeqNum + 1,
-                                              User, Password,
-                                              Salt1, LogFun)
-               end,
-           case AuthRes of
-               {ok, <<0:8, _Rest/binary>>, _RecvNum} ->
-                   {ok,Version};
-               {ok, <<255:8, Code:16/little, Message/binary>>, _RecvNum} ->
-                   mysql:log(LogFun, error, "mysql_conn: "
-                             "init error ~p: ~p~n",
-                             [Code, binary_to_list(Message)]),
-                   {error, binary_to_list(Message)};
-               {ok, RecvPacket, _RecvNum} ->
-                   mysql:log(LogFun, error, "mysql_conn: "
-                             "init unknown error ~p~n",
-                             [binary_to_list(RecvPacket)]),
-                   {error, binary_to_list(RecvPacket)};
-               {error, Reason} ->
-                   mysql:log(LogFun, error, "mysql_conn: "
-                             "init failed receiving data : ~p~n",
-                             [Reason]),
-                   {error, Reason}
-           end;
-       {error, Reason} ->
-           {error, Reason}
-    end.
-
-%% part of mysql_init/4
-greeting(Packet, LogFun) ->
-    <<Protocol:8, Rest/binary>> = Packet,
-    {Version, Rest2} = asciz(Rest),
-    <<_TreadID:32/little, Rest3/binary>> = Rest2,
-    {Salt, Rest4} = asciz(Rest3),
-    <<Caps:16/little, Rest5/binary>> = Rest4,
-    <<ServerChar:16/binary-unit:8, Rest6/binary>> = Rest5,
-    {Salt2, _Rest7} = asciz(Rest6),
-    mysql:log(LogFun, debug, "mysql_conn: greeting version ~p (protocol ~p) "
-             "salt ~p caps ~p serverchar ~p salt2 ~p",
-             [Version, Protocol, Salt, Caps, ServerChar, Salt2]),
-    {normalize_version(Version, LogFun), Salt, Salt2, Caps}.
-
-%% part of greeting/2
-asciz(Data) when is_binary(Data) ->
-    mysql:asciz_binary(Data, []);
-asciz(Data) when is_list(Data) ->
-    {String, [0 | Rest]} = lists:splitwith(fun (C) ->
-                                                  C /= 0
-                                          end, Data),
-    {String, Rest}.
-
-%%--------------------------------------------------------------------
-%% Function: get_query_response(LogFun, RecvPid)
-%%           LogFun  = undefined | function() with arity 3
-%%           RecvPid = pid(), mysql_recv process
-%%           Version = integer(), Representing MySQL version used
-%% Descrip.: Wait for frames until we have a complete query response.
-%% Returns :   {data, #mysql_result}
-%%             {updated, #mysql_result}
-%%             {error, #mysql_result}
-%%           FieldInfo    = list() of term()
-%%           Rows         = list() of [string()]
-%%           AffectedRows = int()
-%%           Reason       = term()
-%%--------------------------------------------------------------------
-get_query_response(LogFun, RecvPid, Version, Options) ->
-    case do_recv(LogFun, RecvPid, undefined) of
-       {ok, <<Fieldcount:8, Rest/binary>>, _} ->
-           case Fieldcount of
-               0 ->
-                   %% No Tabular data
-                   <<AffectedRows:8, _Rest2/binary>> = Rest,
-                   {updated, #mysql_result{affectedrows=AffectedRows}};
-               255 ->
-                   <<_Code:16/little, Message/binary>>  = Rest,
-                   {error, #mysql_result{error=binary_to_list(Message)}};
-               _ ->
-                   %% Tabular data received
-                    ResultType = get_option(result_type, Options, ?DEFAULT_RESULT_TYPE),
-                   case get_fields(LogFun, RecvPid, [], Version, ResultType) of
-                       {ok, Fields} ->
-                           case get_rows(Fieldcount, LogFun, RecvPid, ResultType, []) of
-                               {ok, Rows} ->
-                                   {data, #mysql_result{fieldinfo=Fields,
-                                                        rows=Rows}};
-                               {error, Reason} ->
-                                   {error, #mysql_result{error=Reason}}
-                           end;
-                       {error, Reason} ->
-                           {error, #mysql_result{error=Reason}}
-                   end
-           end;
-       {error, Reason} ->
-           {error, #mysql_result{error=Reason}}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: get_fields(LogFun, RecvPid, [], Version)
-%%           LogFun  = undefined | function() with arity 3
-%%           RecvPid = pid(), mysql_recv process
-%%           Version = integer(), Representing MySQL version used
-%% Descrip.: Received and decode field information.
-%% Returns : {ok, FieldInfo} |
-%%           {error, Reason}
-%%           FieldInfo = list() of term()
-%%           Reason    = term()
-%%--------------------------------------------------------------------
-%% Support for MySQL 4.0.x:
-get_fields(LogFun, RecvPid, Res, ?MYSQL_4_0, ResultType) ->
-    case do_recv(LogFun, RecvPid, undefined) of
-       {ok, Packet, _Num} ->
-           case Packet of
-               <<254:8>> ->
-                   {ok, lists:reverse(Res)};
-               <<254:8, Rest/binary>> when size(Rest) < 8 ->
-                   {ok, lists:reverse(Res)};
-               _ ->
-                   {Table, Rest} = get_with_length(Packet),
-                   {Field, Rest2} = get_with_length(Rest),
-                   {LengthB, Rest3} = get_with_length(Rest2),
-                   LengthL = size(LengthB) * 8,
-                   <<Length:LengthL/little>> = LengthB,
-                   {Type, Rest4} = get_with_length(Rest3),
-                   {_Flags, _Rest5} = get_with_length(Rest4),
-                    if ResultType == list ->
-                            This = {binary_to_list(Table),
-                                    binary_to_list(Field),
-                                    Length,
-                                    %% TODO: Check on MySQL 4.0 if types are specified
-                                    %%       using the same 4.1 formalism and could
-                                    %%       be expanded to atoms:
-                                    binary_to_list(Type)};
-                       ResultType == binary ->
-                            This = {Table, Field, Length, Type}
-                    end,
-                   get_fields(LogFun, RecvPid, [This | Res],
-                               ?MYSQL_4_0, ResultType)
-           end;
-       {error, Reason} ->
-           {error, Reason}
-    end;
-%% Support for MySQL 4.1.x and 5.x:
-get_fields(LogFun, RecvPid, Res, ?MYSQL_4_1, ResultType) ->
-    case do_recv(LogFun, RecvPid, undefined) of
-       {ok, Packet, _Num} ->
-           case Packet of
-               <<254:8>> ->
-                   {ok, lists:reverse(Res)};
-               <<254:8, Rest/binary>> when size(Rest) < 8 ->
-                   {ok, lists:reverse(Res)};
-               _ ->
-                   {_Catalog, Rest} = get_with_length(Packet),
-                   {_Database, Rest2} = get_with_length(Rest),
-                   {Table, Rest3} = get_with_length(Rest2),
-                   %% OrgTable is the real table name if Table is an alias
-                   {_OrgTable, Rest4} = get_with_length(Rest3),
-                   {Field, Rest5} = get_with_length(Rest4),
-                   %% OrgField is the real field name if Field is an alias
-                   {_OrgField, Rest6} = get_with_length(Rest5),
-
-                   <<_Metadata:8/little, _Charset:16/little,
-                    Length:32/little, Type:8/little,
-                    _Flags:16/little, _Decimals:8/little,
-                    _Rest7/binary>> = Rest6,
-                    if ResultType == list ->
-                            This = {binary_to_list(Table),
-                                    binary_to_list(Field),
-                                    Length,
-                                    get_field_datatype(Type)};
-                       ResultType == binary ->
-                            This = {Table, Field, Length,
-                                    get_field_datatype(Type)}
-                    end,
-                   get_fields(LogFun, RecvPid, [This | Res],
-                               ?MYSQL_4_1, ResultType)
-           end;
-       {error, Reason} ->
-           {error, Reason}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: get_rows(N, LogFun, RecvPid, [])
-%%           N       = integer(), number of rows to get
-%%           LogFun  = undefined | function() with arity 3
-%%           RecvPid = pid(), mysql_recv process
-%% Descrip.: Receive and decode a number of rows.
-%% Returns : {ok, Rows} |
-%%           {error, Reason}
-%%           Rows = list() of [string()]
-%%--------------------------------------------------------------------
-get_rows(N, LogFun, RecvPid, ResultType, Res) ->
-    case do_recv(LogFun, RecvPid, undefined) of
-       {ok, Packet, _Num} ->
-           case Packet of
-               <<254:8, Rest/binary>> when size(Rest) < 8 ->
-                   {ok, lists:reverse(Res)};
-               _ ->
-                   {ok, This} = get_row(N, Packet, ResultType, []),
-                   get_rows(N, LogFun, RecvPid, ResultType, [This | Res])
-           end;
-       {error, Reason} ->
-           {error, Reason}
-    end.
-
-
-%% part of get_rows/4
-get_row(0, _Data, _ResultType, Res) ->
-    {ok, lists:reverse(Res)};
-get_row(N, Data, ResultType, Res) ->
-    {Col, Rest} = get_with_length(Data),
-    This = case Col of
-              null ->
-                  null;
-              _ ->
-                  if
-                      ResultType == list ->
-                          binary_to_list(Col);
-                      ResultType == binary ->
-                          Col
-                  end
-          end,
-    get_row(N - 1, Rest, ResultType, [This | Res]).
-
-get_with_length(<<251:8, Rest/binary>>) ->
-    {null, Rest};
-get_with_length(<<252:8, Length:16/little, Rest/binary>>) ->
-    split_binary(Rest, Length);
-get_with_length(<<253:8, Length:24/little, Rest/binary>>) ->
-    split_binary(Rest, Length);
-get_with_length(<<254:8, Length:64/little, Rest/binary>>) ->
-    split_binary(Rest, Length);
-get_with_length(<<Length:8, Rest/binary>>) when Length < 251 ->
-    split_binary(Rest, Length).
-
-close_connection(State) ->
-    Result = gen_tcp:close(State#state.socket),
-    mysql:log(State#state.log_fun,  normal, "Closing connection ~p: ~p~n",
-             [State#state.socket, Result]),
-    Result.
-
-
-%%--------------------------------------------------------------------
-%% Function: do_query(State, Query)
-%%           do_query(Sock, RecvPid, LogFun, Query)
-%%           Sock    = term(), gen_tcp socket
-%%           RecvPid = pid(), mysql_recv process
-%%           LogFun  = undefined | function() with arity 3
-%%           Query   = string()
-%% Descrip.: Send a MySQL query and block awaiting it's response.
-%% Returns : result of get_query_response/2 | {error, Reason}
-%%--------------------------------------------------------------------
-do_query(State, Query, Options) when is_record(State, state) ->
-    do_query(State#state.socket,
-            State#state.recv_pid,
-            State#state.log_fun,
-            Query,
-            State#state.mysql_version,
-            Options
-           ).
-
-do_query(Sock, RecvPid, LogFun, Query, Version, Options) when is_pid(RecvPid),
-                                                             is_list(Query) ->
-    Packet = list_to_binary([?MYSQL_QUERY_OP, Query]),
-    case do_send(Sock, Packet, 0, LogFun) of
-       ok ->
-           get_query_response(LogFun, RecvPid, Version, Options);
-       {error, Reason} ->
-           Msg = io_lib:format("Failed sending data on socket : ~p", [Reason]),
-           {error, Msg}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: do_send(Sock, Packet, SeqNum, LogFun)
-%%           Sock   = term(), gen_tcp socket
-%%           Packet = binary()
-%%           SeqNum = integer(), packet sequence number
-%%           LogFun = undefined | function() with arity 3
-%% Descrip.: Send a packet to the MySQL server.
-%% Returns : result of gen_tcp:send/2
-%%--------------------------------------------------------------------
-do_send(Sock, Packet, SeqNum, _LogFun) when is_binary(Packet),
-                                           is_integer(SeqNum) ->
-    Data = <<(size(Packet)):24/little, SeqNum:8, Packet/binary>>,
-    %%mysql:log(LogFun, debug, "mysql_conn: send packet ~p: ~p",
-    %%[SeqNum, Data]),
-    gen_tcp:send(Sock, Data).
-
-%%--------------------------------------------------------------------
-%% Function: normalize_version(Version, LogFun)
-%%           Version  = string()
-%%           LogFun   = undefined | function() with arity 3
-%% Descrip.: Return a flag corresponding to the MySQL version used.
-%%           The protocol used depends on this flag.
-%% Returns : Version = string()
-%%--------------------------------------------------------------------
-normalize_version([$4,$.,$0|_T], LogFun) ->
-    mysql:log(LogFun, debug, "Switching to MySQL 4.0.x protocol.~n"),
-    ?MYSQL_4_0;
-normalize_version([$4,$.,$1|_T], _LogFun) ->
-    ?MYSQL_4_1;
-normalize_version([$5|_T], _LogFun) ->
-    %% MySQL version 5.x protocol is compliant with MySQL 4.1.x:
-    ?MYSQL_4_1;
-normalize_version(_Other, LogFun) ->
-    mysql:log(LogFun, error, "MySQL version not supported: MySQL Erlang "
-             "module might not work correctly.~n"),
-    %% Error, but trying the oldest protocol anyway:
-    ?MYSQL_4_0.
-
-%%--------------------------------------------------------------------
-%% Function: get_field_datatype(DataType)
-%%           DataType = integer(), MySQL datatype
-%% Descrip.: Return MySQL field datatype as description string
-%% Returns : String, MySQL datatype
-%%--------------------------------------------------------------------
-get_field_datatype(0) ->   'DECIMAL';
-get_field_datatype(1) ->   'TINY';
-get_field_datatype(2) ->   'SHORT';
-get_field_datatype(3) ->   'LONG';
-get_field_datatype(4) ->   'FLOAT';
-get_field_datatype(5) ->   'DOUBLE';
-get_field_datatype(6) ->   'NULL';
-get_field_datatype(7) ->   'TIMESTAMP';
-get_field_datatype(8) ->   'LONGLONG';
-get_field_datatype(9) ->   'INT24';
-get_field_datatype(10) ->  'DATE';
-get_field_datatype(11) ->  'TIME';
-get_field_datatype(12) ->  'DATETIME';
-get_field_datatype(13) ->  'YEAR';
-get_field_datatype(14) ->  'NEWDATE';
-get_field_datatype(16) ->  'BIT';
-get_field_datatype(246) -> 'DECIMAL';
-get_field_datatype(247) -> 'ENUM';
-get_field_datatype(248) -> 'SET';
-get_field_datatype(249) -> 'TINYBLOB';
-get_field_datatype(250) -> 'MEDIUM_BLOG';
-get_field_datatype(251) -> 'LONG_BLOG';
-get_field_datatype(252) -> 'BLOB';
-get_field_datatype(253) -> 'VAR_STRING';
-get_field_datatype(254) -> 'STRING';
-get_field_datatype(255) -> 'GEOMETRY'.
-
-%%--------------------------------------------------------------------
-%% Function: get_option(Key1, Options, Default) -> Value1
-%%           Options = [Option]
-%%           Option = {Key2, Value2}
-%%           Key1 = Key2 = atom()
-%%           Value1 = Value2 = Default = term()
-%% Descrip.: Return the option associated with Key passed to squery/4
-%%--------------------------------------------------------------------
-
-get_option(Key, Options, Default) ->
-    case lists:keysearch(Key, 1, Options) of
-       {value, {_, Value}} ->
-           Value;
-       false ->
-           Default
-    end.
diff --git a/src/mysql/mysql_recv.erl b/src/mysql/mysql_recv.erl
deleted file mode 100644 (file)
index 1d24ded..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : mysql_recv.erl
-%%% Author  : Fredrik Thulin <ft@it.su.se>
-%%% Descrip.: Handles data being received on a MySQL socket. Decodes
-%%%           per-row framing and sends each row to parent.
-%%%
-%%% Created :  4 Aug 2005 by Fredrik Thulin <ft@it.su.se>
-%%%
-%%% Note    : All MySQL code was written by Magnus Ahltorp, originally
-%%%           in the file mysql.erl - I just moved it here.
-%%%
-%%% Copyright (c) 2001-2004 Kungliga Tekniska Högskolan
-%%% See the file COPYING
-%%%
-%%%           Signals this receiver process can send to it's parent
-%%%             (the parent is a mysql_conn connection handler) :
-%%%
-%%%             {mysql_recv, self(), data, Packet, Num}
-%%%             {mysql_recv, self(), closed, {error, Reason}}
-%%%             {mysql_recv, self(), closed, normal}
-%%%
-%%%           Internally (from inside init/4 to start_link/4) the
-%%%           following signals may be sent to the parent process :
-%%%
-%%%             {mysql_recv, self(), init, {ok, Sock}}
-%%%             {mysql_recv, self(), init, {error, E}}
-%%%
-%%%-------------------------------------------------------------------
--module(mysql_recv).
-
-%%--------------------------------------------------------------------
-%% External exports (should only be used by the 'mysql_conn' module)
-%%--------------------------------------------------------------------
--export([start_link/4
-       ]).
-
--record(state, {
-         socket,
-         parent,
-         log_fun,
-         data
-        }).
-
--define(SECURE_CONNECTION, 32768).
--define(CONNECT_TIMEOUT, 5000).
-
-%%====================================================================
-%% External functions
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: start_link(Host, Port, LogFun, Parent)
-%%           Host = string()
-%%           Port = integer()
-%%           LogFun = undefined | function() of arity 3
-%%           Parent = pid(), process that should get received frames
-%% Descrip.: Start a process that connects to Host:Port and waits for
-%%           data. When it has received a MySQL frame, it sends it to
-%%           Parent and waits for the next frame.
-%% Returns : {ok, RecvPid, Socket} |
-%%           {error, Reason}
-%%           RecvPid = pid(), receiver process pid
-%%           Socket  = term(), gen_tcp socket
-%%           Reason  = atom() | string()
-%%--------------------------------------------------------------------
-start_link(Host, Port, LogFun, Parent) when is_list(Host), is_integer(Port) ->
-    RecvPid =
-       spawn_link(fun () ->
-                          init(Host, Port, LogFun, Parent)
-                  end),
-    %% wait for the socket from the spawned pid
-    receive
-       {mysql_recv, RecvPid, init, {error, E}} ->
-           {error, E};
-       {mysql_recv, RecvPid, init, {ok, Socket}} ->
-           {ok, RecvPid, Socket}
-    after ?CONNECT_TIMEOUT ->
-           catch exit(RecvPid, kill),
-           {error, "timeout"}
-    end.
-
-
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% Function: init((Host, Port, LogFun, Parent)
-%%           Host = string()
-%%           Port = integer()
-%%           LogFun = undefined | function() of arity 3
-%%           Parent = pid(), process that should get received frames
-%% Descrip.: Connect to Host:Port and then enter receive-loop.
-%% Returns : error | never returns
-%%--------------------------------------------------------------------
-init(Host, Port, LogFun, Parent) ->
-    case gen_tcp:connect(Host, Port, [binary, {packet, 0}]) of
-       {ok, Sock} ->
-           Parent ! {mysql_recv, self(), init, {ok, Sock}},
-           State = #state{socket  = Sock,
-                          parent  = Parent,
-                          log_fun = LogFun,
-                          data    = <<>>
-                         },
-           loop(State);
-       E ->
-           mysql:log(LogFun, error,
-                     "mysql_recv: Failed connecting to ~p:~p : ~p",
-                     [Host, Port, E]),
-           Msg = lists:flatten(io_lib:format("connect failed : ~p", [E])),
-           Parent ! {mysql_recv, self(), init, {error, Msg}}
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: loop(State)
-%%           State = state record()
-%% Descrip.: The main loop. Wait for data from our TCP socket and act
-%%           on received data or signals that our socket was closed.
-%% Returns : error | never returns
-%%--------------------------------------------------------------------
-loop(State) ->
-    Sock = State#state.socket,
-    receive
-       {tcp, Sock, InData} ->
-           NewData = list_to_binary([State#state.data, InData]),
-           %% send data to parent if we have enough data
-           Rest = sendpacket(State#state.parent, NewData),
-           loop(State#state{data = Rest});
-       {tcp_error, Sock, Reason} ->
-           mysql:log(State#state.log_fun, error, "mysql_recv: "
-                     "Socket ~p closed : ~p", [Sock, Reason]),
-           State#state.parent ! {mysql_recv, self(), closed,
-                                 {error, Reason}},
-           error;
-       {tcp_closed, Sock} ->
-           mysql:log(State#state.log_fun, debug, "mysql_recv: "
-                     "Socket ~p closed", [Sock]),
-           State#state.parent ! {mysql_recv, self(), closed, normal},
-           error
-    end.
-
-%%--------------------------------------------------------------------
-%% Function: sendpacket(Parent, Data)
-%%           Parent = pid()
-%%           Data   = binary()
-%% Descrip.: Check if we have received one or more complete frames by
-%%           now, and if so - send them to Parent.
-%% Returns : Rest = binary()
-%%--------------------------------------------------------------------
-%% send data to parent if we have enough data
-sendpacket(Parent, Data) ->
-    case Data of
-       <<Length:24/little, Num:8, D/binary>> ->
-           if
-               Length =< size(D) ->
-                   {Packet, Rest} = split_binary(D, Length),
-                   Parent ! {mysql_recv, self(), data, Packet, Num},
-                   sendpacket(Parent, Rest);
-               true ->
-                   Data
-           end;
-       _ ->
-           Data
-    end.
similarity index 100%
rename from src/mod_pubsub/node_dag.erl
rename to src/node_dag.erl
similarity index 99%
rename from src/mod_pubsub/node_mb.erl
rename to src/node_mb.erl
index b93a57eb54114c9cf1ed8f723767e0fd0334169e..c626b7a93ab86cec741f3d83e1cd905de62a19ab 100644 (file)
@@ -39,6 +39,7 @@
 -author('eric@ohmforce.com').
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("pubsub.hrl").
 
similarity index 99%
rename from src/mod_pubsub/node_pep.erl
rename to src/node_pep.erl
index 38a9bcec7b5494ec67ce81760d6d4c1b23aad0c3..40ff84d5bf1a381537032fdd44d06b684cde5e64 100644 (file)
@@ -33,6 +33,7 @@
 -author('christophe.romain@process-one.net').
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("pubsub.hrl").
 
similarity index 99%
rename from src/mod_pubsub/node_pep_odbc.erl
rename to src/node_pep_odbc.erl
index 8f4f36a450268bd7c57ed5ef10cac90b761f5f48..d997d9ce1e49a95173b24b7ecdba16deb5ab7dcb 100644 (file)
@@ -33,6 +33,7 @@
 -author('christophe.romain@process-one.net').
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("pubsub.hrl").
 
similarity index 99%
rename from src/mod_pubsub/nodetree_dag.erl
rename to src/nodetree_dag.erl
index 2be3e352283cc66689ebf610e4b9608630b2ac9c..e8ad8b14195c79e92b6a37ca735f7fbc5a1ba016 100644 (file)
@@ -29,6 +29,7 @@
 -include_lib("stdlib/include/qlc.hrl").
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -include("pubsub.hrl").
 
diff --git a/src/odbc/Makefile.in b/src/odbc/Makefile.in
deleted file mode 100644 (file)
index 3f4898d..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -D@db_type@ -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/odbc/Makefile.win32 b/src/odbc/Makefile.win32
deleted file mode 100644 (file)
index 2775468..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\ejabberd_odbc.beam ..\ejabberd_odbc_sup.beam ..\odbc_queries.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\ejabberd_odbc.beam : ejabberd_odbc.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_odbc.erl
-
-$(OUTDIR)\ejabberd_odbc_sup.beam : ejabberd_odbc_sup.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_odbc_sup.erl
-
-$(OUTDIR)\odbc_queries.beam : odbc_queries.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) -D$(DBTYPE) odbc_queries.erl
-
similarity index 99%
rename from src/odbc/odbc_queries.erl
rename to src/odbc_queries.erl
index 66da7906fc42fb3147265a5f740618fc01955f28..e8fb473792f0b2f2c94c593dccf76985f1a7896d 100644 (file)
@@ -72,6 +72,7 @@
 -endif.
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 %% Almost a copy of string:join/2.
 %% We use this version because string:join/2 is relatively
diff --git a/src/pam/Makefile.in b/src/pam/Makefile.in
deleted file mode 100644 (file)
index bde2894..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# $Id: Makefile.in 775 2007-05-29 14:31:12Z mremond $
-
-CC = @CC@
-CFLAGS = @CFLAGS@ @PAM_CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@ @PAM_LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-ERLSHLIBS = ../epam
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS) $(ERLSHLIBS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-#all:  $(ERLSHLIBS)
-#      erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
-
-$(ERLSHLIBS):  ../%:   %.c
-                       $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
-                       $(subst ../,,$(subst ,.c,$@)) $(LIBS) \
-                       $(ERLANG_LIBS) $(ERLANG_CFLAGS) \
-                       -o $@ -lpthread
-
-clean:
-       rm -f $(BEAMS) $(ERLSHLIBS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
diff --git a/src/pam/epam.c b/src/pam/epam.c
deleted file mode 100644 (file)
index bbb0fa4..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013   ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include <security/pam_appl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <erl_interface.h>
-#include <ei.h>
-#include <unistd.h>
-
-#define dec_int16(s) ((((unsigned char*)  (s))[0] << 8) | \
-                      (((unsigned char*)  (s))[1]))
-
-#define enc_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \
-                        ((unsigned char*)(s))[1] = (i)         & 0xff;}
-
-#define BUFSIZE (1 << 16)
-#define CMD_AUTH 0
-#define CMD_ACCT 1
-
-typedef unsigned char byte;
-
-#ifdef PAM_FAIL_DELAY
-static void delay_fn(int retval, unsigned usec_delay, void *appdata_ptr)
-{
-  /* No delay. However, looks like some PAM modules ignore this */
-}
-#endif
-
-static int misc_conv(int num_msg,
-                    const struct pam_message **msg,
-                    struct pam_response **resp,
-                    void *password)
-{
-  int msg_style;
-  if (num_msg != 1)
-    return PAM_CONV_ERR;
-  msg_style = msg[0]->msg_style;
-  if ((msg_style != PAM_PROMPT_ECHO_OFF) && (msg_style != PAM_PROMPT_ECHO_ON))
-    return PAM_CONV_ERR;
-  *resp = malloc(sizeof(struct pam_response));
-  (*resp)[0].resp_retcode = 0;
-  (*resp)[0].resp = strdup(password);
-  return PAM_SUCCESS;
-}
-
-static int auth(char *service, char *user, char *password)
-{
-  struct pam_conv conv = {misc_conv, password};
-  int retval;
-  pam_handle_t *pamh = NULL;
-  retval = pam_start(service, user, &conv, &pamh);
-  if (retval == PAM_SUCCESS)
-    retval = pam_set_item(pamh, PAM_RUSER, user);
-#ifdef PAM_FAIL_DELAY
-  if (retval == PAM_SUCCESS)
-    retval = pam_set_item(pamh, PAM_FAIL_DELAY, (void *)delay_fn);
-#endif
-  if (retval == PAM_SUCCESS)
-    retval = pam_authenticate(pamh, 0);
-  if (retval == PAM_SUCCESS)
-    retval = pam_acct_mgmt(pamh, 0);
-  pam_end(pamh, retval);
-  return retval;
-}
-
-static int acct_mgmt(char *service, char *user)
-{
-  struct pam_conv conv = {misc_conv, NULL};
-  int retval;
-  pam_handle_t *pamh = NULL;
-  retval = pam_start(service, user, &conv, &pamh);
-  if (retval == PAM_SUCCESS)
-    retval = pam_set_item(pamh, PAM_RUSER, user);
-#ifdef PAM_FAIL_DELAY
-  if (retval == PAM_SUCCESS)
-    retval = pam_set_item(pamh, PAM_FAIL_DELAY, (void *)delay_fn);
-#endif
-  if (retval == PAM_SUCCESS)
-    retval = pam_acct_mgmt(pamh, 0);
-  pam_end(pamh, retval);
-  return retval;
-}
-
-static int read_buf(int fd, byte *buf, int len)
-{
-  int i, got = 0;
-  do {
-    if ((i = read(fd, buf+got, len-got)) <= 0) {
-      if (i == 0) return got;
-      if (errno != EINTR)
-       return got;
-      i = 0;
-    }
-    got += i;
-  } while (got < len);
-  return (len);
-}
-
-static int read_cmd(byte *buf)
-{
-  int len;
-  if (read_buf(0, buf, 2) != 2)
-    return 0;
-  len = dec_int16(buf);
-  if (read_buf(0, buf, len) != len)
-    return 0;
-  return 1;
-}
-
-static int write_buf(int fd, char *buf, int len)
-{
-  int i, done = 0; 
-  do {
-    if ((i = write(fd, buf+done, len-done)) < 0) {
-      if (errno != EINTR)
-       return (i);
-      i = 0;
-    }
-    done += i;
-  } while (done < len);
-  return (len);
-}
-
-static int write_cmd(char *buf, int len)
-{
-  byte hd[2];
-  enc_int16(len, hd);
-  if (write_buf(1, (char *)hd, 2) != 2)
-    return 0;
-  if (write_buf(1, buf, len) != len)
-    return 0;
-  return 1;
-}
-
-static int process_reply(ETERM *pid, int cmd, int res)
-{
-  ETERM *result;
-  int len, retval;
-  const char *errtxt;
-  byte *buf;
-  if (res == PAM_SUCCESS)
-    result = erl_format("{~i, ~w, true}", cmd, pid);
-  else
-    {
-      errtxt = pam_strerror(NULL, res);
-      result = erl_format("{~i, ~w, {false, ~s}}", cmd, pid, errtxt);
-    }
-  len = erl_term_len(result);
-  buf = erl_malloc(len);
-  erl_encode(result, buf);
-  retval = write_cmd((char *)buf, len);
-  erl_free_term(result);
-  erl_free(buf);
-  return retval;
-}
-
-static int process_acct(ETERM *pid, ETERM *data)
-{
-  int retval = 0;
-  ETERM *pattern, *srv, *user;
-  char *service, *username;
-  pattern = erl_format("{Srv, User}");
-  if (erl_match(pattern, data))
-    {
-      srv = erl_var_content(pattern, "Srv");
-      service = erl_iolist_to_string(srv);
-      user = erl_var_content(pattern, "User");
-      username = erl_iolist_to_string(user);
-      retval = process_reply(pid, CMD_ACCT, acct_mgmt(service, username));
-      erl_free_term(srv);
-      erl_free_term(user);
-      erl_free(service);
-      erl_free(username);
-    }
-  erl_free_term(pattern);
-  return retval;
-}
-
-static int process_auth(ETERM *pid, ETERM *data)
-{
-  int retval = 0;
-  ETERM *pattern, *srv, *user, *pass;
-  char *service, *username, *password;
-  pattern = erl_format("{Srv, User, Pass}");
-  if (erl_match(pattern, data))
-    {
-      srv = erl_var_content(pattern, "Srv");
-      service = erl_iolist_to_string(srv);
-      user = erl_var_content(pattern, "User");
-      username = erl_iolist_to_string(user);
-      pass = erl_var_content(pattern, "Pass");
-      password = erl_iolist_to_string(pass);
-      retval = process_reply(pid, CMD_AUTH, auth(service, username, password));
-      erl_free_term(srv);
-      erl_free_term(user);
-      erl_free_term(pass);
-      erl_free(service);
-      erl_free(username);
-      erl_free(password);
-    };
-  erl_free_term(pattern);
-  return retval;
-}
-
-static int process_command(byte *buf)
-{
-  int retval = 0;
-  ETERM *pattern, *tuple, *cmd, *port, *data;
-  pattern = erl_format("{Cmd, Port, Data}");
-  tuple = erl_decode(buf);
-  if (erl_match(pattern, tuple))
-    {
-      cmd = erl_var_content(pattern, "Cmd");
-      port = erl_var_content(pattern, "Port");
-      data = erl_var_content(pattern, "Data");
-      switch (ERL_INT_VALUE(cmd))
-       {
-       case CMD_AUTH:
-         retval = process_auth(port, data);
-         break;
-       case CMD_ACCT:
-         retval = process_acct(port, data);
-         break;
-       };
-      erl_free_term(cmd);
-      erl_free_term(port);
-      erl_free_term(data);
-    }
-  erl_free_term(pattern);
-  erl_free_term(tuple);
-  return retval;
-}
-
-static void loop(void)
-{
-  byte buf[BUFSIZE];
-  int retval = 0;
-  do {
-    if (read_cmd(buf) > 0)
-      retval = process_command(buf);
-    else
-      retval = 0;
-  } while (retval);
-}
-
-int main(int argc, char *argv[])
-{
-  erl_init(NULL, 0);
-  loop();
-  return 0;
-}
diff --git a/src/pam/epam.erl b/src/pam/epam.erl
deleted file mode 100644 (file)
index e0ea171..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : epam.erl
-%%% Author  : Evgeniy Khramtsov <xram@jabber.ru>
-%%% Purpose : PAM authentication and accounting management
-%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%-------------------------------------------------------------------
-
--module(epam).
-
--author('xram@jabber.ru').
-
--behaviour(gen_server).
-
--include_lib("kernel/include/file.hrl").
-
--include("ejabberd.hrl").
-
-%% API
--export([start_link/0, start/0, stop/0]).
-
--export([authenticate/3, acct_mgmt/2]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2,
-        handle_info/2, terminate/2, code_change/3]).
-
--define(WARNING,
-       "File ~p is world-wide executable. This "
-        "is a possible security hole in your "
-        "system. This file must be setted root "
-        "on execution and only ejabberd must "
-        "be able to read/execute it. You have "
-        "been warned :)").
-
--define(PROCNAME, ?MODULE).
-
--define(CMD_AUTH, 0).
-
--define(CMD_ACCT, 1).
-
--record(state, {port}).
-
-%%====================================================================
-%% API
-%%====================================================================
-start() ->
-    ChildSpec = {?PROCNAME, {?MODULE, start_link, []},
-                transient, 1000, worker, [?MODULE]},
-    supervisor:start_child(ejabberd_sup, ChildSpec).
-
-stop() ->
-    gen_server:call(?PROCNAME, stop),
-    supervisor:terminate_child(ejabberd_sup, ?PROCNAME),
-    supervisor:delete_child(ejabberd_sup, ?PROCNAME).
-
-start_link() ->
-    gen_server:start_link({local, ?PROCNAME}, ?MODULE, [],
-                         []).
-
-authenticate(Srv, User, Pass)
-    when is_binary(Srv), is_binary(User), is_binary(Pass) ->
-    gen_server:call(?PROCNAME,
-                   {authenticate, Srv, User, Pass}).
-
-acct_mgmt(Srv, User)
-    when is_binary(Srv), is_binary(User) ->
-    gen_server:call(?PROCNAME, {acct_mgmt, Srv, User}).
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-init([]) ->
-    FileName = filename:join(ejabberd:get_bin_path(),
-                            "epam"),
-    case file:read_file_info(FileName) of
-      {ok, Info} ->
-         Mode = Info#file_info.mode band 2049,
-         if Mode == 2049 -> ?WARNING_MSG((?WARNING), [FileName]);
-            true -> ok
-         end,
-         Port = open_port({spawn, FileName},
-                          [{packet, 2}, binary, exit_status]),
-         {ok, #state{port = Port}};
-      {error, Reason} ->
-         ?ERROR_MSG("Can't open file ~p: ~p",
-                    [FileName, Reason]),
-         error
-    end.
-
-terminate(_Reason, #state{port = Port}) ->
-    catch port_close(Port), ok.
-
-handle_call({authenticate, Srv, User, Pass}, From,
-           State) ->
-    Port = State#state.port,
-    Data = term_to_binary({?CMD_AUTH, From,
-                          {Srv, User, Pass}}),
-    port_command(Port, Data),
-    {noreply, State};
-handle_call({acct_mgmt, Srv, User}, From, State) ->
-    Port = State#state.port,
-    Data = term_to_binary({?CMD_ACCT, From, {Srv, User}}),
-    port_command(Port, Data),
-    {noreply, State};
-handle_call(stop, _From, State) ->
-    {stop, normal, ok, State};
-handle_call(_Request, _From, State) ->
-    {reply, bad_request, State}.
-
-handle_info({Port, {data, Data}},
-           #state{port = Port} = State) ->
-    case binary_to_term(Data) of
-      {Cmd, To, Reply}
-         when Cmd == (?CMD_AUTH); Cmd == (?CMD_ACCT) ->
-         gen_server:reply(To, Reply);
-      Err ->
-         ?ERROR_MSG("Got invalid reply from ~p: ~p", [Port, Err])
-    end,
-    {noreply, State};
-handle_info({Port, {exit_status, _}},
-           #state{port = Port} = State) ->
-    {stop, port_died, State};
-handle_info(Msg, State) ->
-    ?WARNING_MSG("Got unexpected message: ~p", [Msg]),
-    {noreply, State}.
-
-handle_cast(_Msg, State) -> {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
diff --git a/src/pgsql/EPLICENSE b/src/pgsql/EPLICENSE
deleted file mode 100644 (file)
index 36aa84e..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-ERLANG PUBLIC LICENSE
-Version 1.1
-
-1. Definitions.
-
-1.1. ``Contributor'' means each entity that creates or contributes to
-the creation of Modifications.
-
-1.2. ``Contributor Version'' means the combination of the Original
-Code, prior Modifications used by a Contributor, and the Modifications
-made by that particular Contributor.
-
-1.3. ``Covered Code'' means the Original Code or Modifications or the
-combination of the Original Code and Modifications, in each case
-including portions thereof.
-
-1.4. ``Electronic Distribution Mechanism'' means a mechanism generally
-accepted in the software development community for the electronic
-transfer of data.
-
-1.5. ``Executable'' means Covered Code in any form other than Source
-Code.
-
-1.6. ``Initial Developer'' means the individual or entity identified
-as the Initial Developer in the Source Code notice required by Exhibit
-A.
-
-1.7. ``Larger Work'' means a work which combines Covered Code or
-portions thereof with code not governed by the terms of this License.
-
-1.8. ``License'' means this document.
-
-1.9. ``Modifications'' means any addition to or deletion from the
-substance or structure of either the Original Code or any previous
-Modifications. When Covered Code is released as a series of files, a
-Modification is:
-
-A. Any addition to or deletion from the contents of a file containing
-   Original Code or previous Modifications. 
-
-B. Any new file that contains any part of the Original Code or
-   previous Modifications. 
-
-1.10. ``Original Code'' means Source Code of computer software code
-which is described in the Source Code notice required by Exhibit A as
-Original Code, and which, at the time of its release under this
-License is not already Covered Code governed by this License.
-
-1.11. ``Source Code'' means the preferred form of the Covered Code for
-making modifications to it, including all modules it contains, plus
-any associated interface definition files, scripts used to control
-compilation and installation of an Executable, or a list of source
-code differential comparisons against either the Original Code or
-another well known, available Covered Code of the Contributor's
-choice. The Source Code can be in a compressed or archival form,
-provided the appropriate decompression or de-archiving software is
-widely available for no charge.
-
-1.12. ``You'' means an individual or a legal entity exercising rights
-under, and complying with all of the terms of, this License. For legal
-entities,``You'' includes any entity which controls, is controlled by,
-or is under common control with You. For purposes of this definition,
-``control'' means (a) the power, direct or indirect, to cause the
-direction or management of such entity, whether by contract or
-otherwise, or (b) ownership of fifty percent (50%) or more of the
-outstanding shares or beneficial ownership of such entity.
-
-2. Source Code License.
-
-2.1. The Initial Developer Grant.
-The Initial Developer hereby grants You a world-wide, royalty-free,
-non-exclusive license, subject to third party intellectual property
-claims:
-
-(a) to use, reproduce, modify, display, perform, sublicense and
-    distribute the Original Code (or portions thereof) with or without
-    Modifications, or as part of a Larger Work; and 
-
-(b) under patents now or hereafter owned or controlled by Initial
-    Developer, to make, have made, use and sell (``Utilize'') the
-    Original Code (or portions thereof), but solely to the extent that
-    any such patent is reasonably necessary to enable You to Utilize
-    the Original Code (or portions thereof) and not to any greater
-    extent that may be necessary to Utilize further Modifications or
-    combinations. 
-
-2.2. Contributor Grant.
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license, subject to third party intellectual property
-claims:
-
-(a) to use, reproduce, modify, display, perform, sublicense and
-    distribute the Modifications created by such Contributor (or
-    portions thereof) either on an unmodified basis, with other
-    Modifications, as Covered Code or as part of a Larger Work; and 
-
-(b) under patents now or hereafter owned or controlled by Contributor,
-    to Utilize the Contributor Version (or portions thereof), but
-    solely to the extent that any such patent is reasonably necessary
-    to enable You to Utilize the Contributor Version (or portions
-    thereof), and not to any greater extent that may be necessary to
-    Utilize further Modifications or combinations. 
-
-3. Distribution Obligations.
-
-3.1. Application of License.
-The Modifications which You contribute are governed by the terms of
-this License, including without limitation Section 2.2. The Source
-Code version of Covered Code may be distributed only under the terms
-of this License, and You must include a copy of this License with
-every copy of the Source Code You distribute. You may not offer or
-impose any terms on any Source Code version that alters or restricts
-the applicable version of this License or the recipients' rights
-hereunder. However, You may include an additional document offering
-the additional rights described in Section 3.5. 
-
-3.2. Availability of Source Code.
-Any Modification which You contribute must be made available in Source
-Code form under the terms of this License either on the same media as
-an Executable version or via an accepted Electronic Distribution
-Mechanism to anyone to whom you made an Executable version available;
-and if made available via Electronic Distribution Mechanism, must
-remain available for at least twelve (12) months after the date it
-initially became available, or at least six (6) months after a
-subsequent version of that particular Modification has been made
-available to such recipients. You are responsible for ensuring that
-the Source Code version remains available even if the Electronic
-Distribution Mechanism is maintained by a third party.
-
-3.3. Description of Modifications.
-You must cause all Covered Code to which you contribute to contain a
-file documenting the changes You made to create that Covered Code and
-the date of any change. You must include a prominent statement that
-the Modification is derived, directly or indirectly, from Original
-Code provided by the Initial Developer and including the name of the
-Initial Developer in (a) the Source Code, and (b) in any notice in an
-Executable version or related documentation in which You describe the
-origin or ownership of the Covered Code.
-
-3.4. Intellectual Property Matters
-
-(a) Third Party Claims.
-    If You have knowledge that a party claims an intellectual property
-    right in particular functionality or code (or its utilization
-    under this License), you must include a text file with the source
-    code distribution titled ``LEGAL'' which describes the claim and
-    the party making the claim in sufficient detail that a recipient
-    will know whom to contact. If you obtain such knowledge after You
-    make Your Modification available as described in Section 3.2, You
-    shall promptly modify the LEGAL file in all copies You make
-    available thereafter and shall take other steps (such as notifying
-    appropriate mailing lists or newsgroups) reasonably calculated to
-    inform those who received the Covered Code that new knowledge has
-    been obtained. 
-
-(b) Contributor APIs.
-    If Your Modification is an application programming interface and
-    You own or control patents which are reasonably necessary to
-    implement that API, you must also include this information in the
-    LEGAL file. 
-
-3.5. Required Notices.
-You must duplicate the notice in Exhibit A in each file of the Source
-Code, and this License in any documentation for the Source Code, where
-You describe recipients' rights relating to Covered Code. If You
-created one or more Modification(s), You may add your name as a
-Contributor to the notice described in Exhibit A. If it is not
-possible to put such notice in a particular Source Code file due to
-its structure, then you must include such notice in a location (such
-as a relevant directory file) where a user would be likely to look for
-such a notice. You may choose to offer, and to charge a fee for,
-warranty, support, indemnity or liability obligations to one or more
-recipients of Covered Code. However, You may do so only on Your own
-behalf, and not on behalf of the Initial Developer or any
-Contributor. You must make it absolutely clear than any such warranty,
-support, indemnity or liability obligation is offered by You alone,
-and You hereby agree to indemnify the Initial Developer and every
-Contributor for any liability incurred by the Initial Developer or
-such Contributor as a result of warranty, support, indemnity or
-liability terms You offer.
-
-3.6. Distribution of Executable Versions.
-You may distribute Covered Code in Executable form only if the
-requirements of Section 3.1-3.5 have been met for that Covered Code,
-and if You include a notice stating that the Source Code version of
-the Covered Code is available under the terms of this License,
-including a description of how and where You have fulfilled the
-obligations of Section 3.2. The notice must be conspicuously included
-in any notice in an Executable version, related documentation or
-collateral in which You describe recipients' rights relating to the
-Covered Code. You may distribute the Executable version of Covered
-Code under a license of Your choice, which may contain terms different
-from this License, provided that You are in compliance with the terms
-of this License and that the license for the Executable version does
-not attempt to limit or alter the recipient's rights in the Source
-Code version from the rights set forth in this License. If You
-distribute the Executable version under a different license You must
-make it absolutely clear that any terms which differ from this License
-are offered by You alone, not by the Initial Developer or any
-Contributor. You hereby agree to indemnify the Initial Developer and
-every Contributor for any liability incurred by the Initial Developer
-or such Contributor as a result of any such terms You offer.
-
-3.7. Larger Works.
-You may create a Larger Work by combining Covered Code with other code
-not governed by the terms of this License and distribute the Larger
-Work as a single product. In such a case, You must make sure the
-requirements of this License are fulfilled for the Covered Code.
-
-4. Inability to Comply Due to Statute or Regulation.
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Code due to statute
-or regulation then You must: (a) comply with the terms of this License
-to the maximum extent possible; and (b) describe the limitations and
-the code they affect. Such description must be included in the LEGAL
-file described in Section 3.4 and must be included with all
-distributions of the Source Code. Except to the extent prohibited by
-statute or regulation, such description must be sufficiently detailed
-for a recipient of ordinary skill to be able to understand it.
-
-5. Application of this License.
-
-This License applies to code to which the Initial Developer has
-attached the notice in Exhibit A, and to related Covered Code.
-
-6. CONNECTION TO MOZILLA PUBLIC LICENSE
-
-This Erlang License is a derivative work of the Mozilla Public
-License, Version 1.0. It contains terms which differ from the Mozilla
-Public License, Version 1.0.
-
-7. DISCLAIMER OF WARRANTY.
-
-COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN ``AS IS'' BASIS,
-WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
-DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
-NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF
-THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE
-IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER
-CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR
-CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART
-OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER
-EXCEPT UNDER THIS DISCLAIMER.
-
-8. TERMINATION.
-This License and the rights granted hereunder will terminate
-automatically if You fail to comply with terms herein and fail to cure
-such breach within 30 days of becoming aware of the breach. All
-sublicenses to the Covered Code which are properly granted shall
-survive any termination of this License. Provisions which, by their
-nature, must remain in effect beyond the termination of this License
-shall survive.
-
-9. DISCLAIMER OF LIABILITY
-Any utilization of Covered Code shall not cause the Initial Developer
-or any Contributor to be liable for any damages (neither direct nor
-indirect).
-
-10. MISCELLANEOUS
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision is held to be unenforceable, such
-provision shall be reformed only to the extent necessary to make it
-enforceable. This License shall be construed by and in accordance with
-the substantive laws of Sweden. Any dispute, controversy or claim
-arising out of or relating to this License, or the breach, termination
-or invalidity thereof, shall be subject to the exclusive jurisdiction
-of Swedish courts, with the Stockholm City Court as the first
-instance.
-       
-EXHIBIT A.
-
-``The contents of this file are subject to the Erlang Public License,
-Version 1.1, (the "License"); you may not use this file except in
-compliance with the License. You should have received a copy of the
-Erlang Public License along with this software. If not, it can be
-retrieved via the world wide web at http://www.erlang.org/.
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-the License for the specific language governing rights and limitations
-under the License.
-
-The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-AB. All Rights Reserved.''
diff --git a/src/pgsql/Makefile.in b/src/pgsql/Makefile.in
deleted file mode 100644 (file)
index e77da84..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id: Makefile.in 1453 2008-07-16 16:58:42Z badlop $
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/pgsql/Makefile.win32 b/src/pgsql/Makefile.win32
deleted file mode 100644 (file)
index e70aba9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\stun_codec.beam ..\ejabberd_stun.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\stun_codec.beam : stun_codec.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) stun_codec.erl
-
-$(OUTDIR)\ejabberd_stun.beam : ejabberd_stun.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_stun.erl
diff --git a/src/pgsql/pgsql.erl b/src/pgsql/pgsql.erl
deleted file mode 100644 (file)
index 3f993ec..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-%%% File    : pgsql.erl
-%%% Author  : Christian Sunesson <chsu79@gmail.com>
-%%% Description : PostgresQL interface
-%%% Created : 11 May 2005
-
-%%
-%% API for accessing the postgres driver.
-%%
-
--module(pgsql).
--export([connect/1, connect/4, connect/5]).
-
--export([squery/2, 
-        pquery/3, 
-        terminate/1, 
-        prepare/3, unprepare/2, 
-        execute/3]).
-
-
-connect(Host, Database, User, Password) ->
-    connect([{database, Database},
-            {host, Host},
-            {user, User},
-            {password, Password}]).
-
-connect(Host, Database, User, Password, Port) ->
-    connect([{database, Database},
-            {host, Host},
-            {user, User},
-            {port, Port},
-            {password, Password}]).
-
-connect(Options) ->
-    pgsql_proto:start(Options).
-
-%% Close a connection
-terminate(Db) ->
-    gen_server:call(Db, terminate).
-
-%%% In the "simple query" protocol, the frontend just sends a 
-%%% textual query string, which is parsed and immediately 
-%%% executed by the backend.  
-
-%% A simple query can contain multiple statements (separated with a semi-colon),
-%% and each statement's response.
-
-%%% squery(Db, Query) -> {ok, Results} | ... no real error handling
-%%% Query = string()
-%%% Results = [Result]
-%%% Result = {"SELECT", RowDesc, ResultSet} | ...
-squery(Db, Query) ->
-    gen_server:call(Db, {squery, Query}, infinity).
-
-%%% In the "extended query" protocol, processing of queries is 
-%%% separated into multiple steps: parsing, binding of parameter
-%%% values, and execution. This offers flexibility and performance
-%%% benefits, at the cost of extra complexity.
-
-%%% pquery(Db, Query, Params) -> {ok, Command, Status, NameTypes, Rows} | timeout | ...
-%%% Query = string()
-%%% Params = [term()]
-%%% Command = string()
-%%% Status = idle | transaction | failed_transaction
-%%% NameTypes = [{ColName, ColType}]
-%%% Rows = [list()]
-pquery(Db, Query, Params) ->
-    gen_server:call(Db, {equery, {Query, Params}}).
-
-%%% prepare(Db, Name, Query) -> {ok, Status, ParamTypes, ResultTypes}
-%%% Status = idle | transaction | failed_transaction
-%%% ParamTypes = [atom()]
-%%% ResultTypes = [{ColName, ColType}]
-prepare(Db, Name, Query) when is_atom(Name) ->
-    gen_server:call(Db, {prepare, {atom_to_list(Name), Query}}).
-
-%%% unprepare(Db, Name) -> ok | timeout | ...
-%%% Name = atom()
-unprepare(Db, Name) when is_atom(Name) ->
-    gen_server:call(Db, {unprepare, atom_to_list(Name)}).
-
-%%% execute(Db, Name, Params) -> {ok, Result} | timeout | ...
-%%% Result = {'INSERT', NRows} |
-%%%          {'DELETE', NRows} |
-%%%          {'SELECT', ResultSet} |
-%%%          ...
-%%% ResultSet = [Row]
-%%% Row = list()
-execute(Db, Name, Params) when is_atom(Name), is_list(Params) ->
-    Ref = make_ref(),
-    Db ! {execute, Ref, self(), {atom_to_list(Name), Params}},
-    receive
-       {pgsql, Ref, Result} ->
-           {ok, Result}
-    after 5000 ->
-           timeout
-    end.
diff --git a/src/pgsql/pgsql_proto.erl b/src/pgsql/pgsql_proto.erl
deleted file mode 100644 (file)
index fe49a48..0000000
+++ /dev/null
@@ -1,650 +0,0 @@
-%%% File    : pgsql_proto.erl
-%%% Author  : Christian Sunesson <chrisu@kth.se>
-%%% Description : PostgreSQL protocol driver
-%%% Created :  9 May 2005
-
-%%% This is the protocol handling part of the PostgreSQL driver, it turns packages into
-%%% erlang term messages and back.
-
--module(pgsql_proto).
-
--behaviour(gen_server).
-
-%% TODO:
-%% When factorizing make clear distinction between message and packet.
-%% Packet == binary on-wire representation
-%% Message = parsed Packet as erlang terms.
-
-%%% Version 3.0 of the protocol.
-%%% Supported in postgres from version 7.4
--define(PROTOCOL_MAJOR, 3).
--define(PROTOCOL_MINOR, 0).
-
-%%% PostgreSQL protocol message codes
--define(PG_BACKEND_KEY_DATA, $K).
--define(PG_PARAMETER_STATUS, $S).
--define(PG_ERROR_MESSAGE, $E).
--define(PG_NOTICE_RESPONSE, $N).
--define(PG_EMPTY_RESPONSE, $I).
--define(PG_ROW_DESCRIPTION, $T).
--define(PG_DATA_ROW, $D).
--define(PG_READY_FOR_QUERY, $Z).
--define(PG_AUTHENTICATE, $R).
--define(PG_BIND, $B).
--define(PG_PARSE, $P).
--define(PG_COMMAND_COMPLETE, $C).
--define(PG_PARSE_COMPLETE, $1).
--define(PG_BIND_COMPLETE, $2).
--define(PG_CLOSE_COMPLETE, $3).
--define(PG_PORTAL_SUSPENDED, $s).
--define(PG_NO_DATA, $n).
-
--export([start/1, start_link/1]).
-
-%% gen_server callbacks
--export([init/1,
-        handle_call/3,
-        handle_cast/2,
-        code_change/3,
-        handle_info/2,
-        terminate/2]).
-
-%% For protocol unwrapping, pgsql_tcp for example.
--export([decode_packet/3]).
--export([encode_message/2]).
--export([encode/2]).
-
--import(pgsql_util, [option/3]).
--import(pgsql_util, [socket/1]).
--import(pgsql_util, [send/2, send_int/2, send_msg/3]).
--import(pgsql_util, [recv_msg/2, recv_msg/1, recv_byte/2, recv_byte/1]).
--import(pgsql_util, [string/1, make_pair/2, split_pair/2]).
--import(pgsql_util, [count_string/1, to_string/2]).
--import(pgsql_util, [coldescs/3, datacoldescs/3]).
--import(pgsql_util, [to_integer/1, to_atom/1]).
-
--record(state, {options, driver, params, socket, oidmap, as_binary}).
-
-start(Options) ->
-    gen_server:start(?MODULE, [self(), Options], []).
-
-start_link(Options) ->
-    gen_server:start_link(?MODULE, [self(), Options], []).
-
-init([DriverPid, Options]) ->
-    %%io:format("Init~n", []),
-    %% Default values: We connect to localhost on the standard TCP/IP
-    %% port.
-    Host = option(Options, host, "localhost"),
-    Port = option(Options, port, 5432),
-    AsBinary = option(Options, as_binary, false),
-
-    case socket({tcp, Host, Port}) of
-       {ok, Sock} ->
-           connect(#state{options = Options,
-                          driver = DriverPid,
-                           as_binary = AsBinary,
-                          socket = Sock});
-       Error ->
-           Reason = {init, Error},
-           {stop, Reason}
-    end.
-
-connect(StateData) ->
-    %%io:format("Connect~n", []),
-    %% Connection settings for database-login.
-    %% TODO: Check if the default values are relevant:
-    UserName = option(StateData#state.options, user, "cos"),
-    DatabaseName = option(StateData#state.options, database, "template1"),
-
-    %% Make protocol startup packet.
-    Version = <<?PROTOCOL_MAJOR:16/integer, ?PROTOCOL_MINOR:16/integer>>,
-    User = make_pair(user, UserName),
-    Database = make_pair(database, DatabaseName),
-    StartupPacket = <<Version/binary,
-                    User/binary,
-                    Database/binary,
-                    0>>,
-
-    %% Backend will continue with authentication after the startup packet
-    PacketSize = 4 + size(StartupPacket),
-    Sock = StateData#state.socket,
-    ok = gen_tcp:send(Sock, <<PacketSize:32/integer, StartupPacket/binary>>),
-    authenticate(StateData).
-
-
-authenticate(StateData) ->
-    %% Await authentication request from backend.
-    Sock = StateData#state.socket,
-    AsBin = StateData#state.as_binary,
-    {ok, Code, Packet} = recv_msg(Sock, 5000),
-    {ok, Value} = decode_packet(Code, Packet, AsBin),
-    case Value of
-       %% Error response
-       {error_message, Message} ->
-           {stop, {authentication, Message}};
-       {authenticate, {AuthMethod, Salt}} ->
-           case AuthMethod of
-               0 -> % Auth ok
-                   setup(StateData, []);
-               1 -> % Kerberos 4
-                   {stop, {nyi, auth_kerberos4}};
-               2 -> % Kerberos 5
-                   {stop, {nyi, auth_kerberos5}};
-               3 -> % Plaintext password
-                   Password = option(StateData#state.options, password, ""),
-                   EncodedPass = encode_message(pass_plain, Password),
-                   ok = send(Sock, EncodedPass),
-                   authenticate(StateData);
-               4 -> % Hashed password
-                   {stop, {nyi, auth_crypt}};
-               5 -> % MD5 password
-                   Password = option(StateData#state.options, password, ""),
-                   User = option(StateData#state.options, user, ""),
-                   EncodedPass = encode_message(pass_md5,
-                                                {User, Password, Salt}),
-                   ok = send(Sock, EncodedPass),
-                   authenticate(StateData);
-               _ ->
-                   {stop, {authentication, {unknown, AuthMethod}}}
-           end;
-       %% Unknown message received
-       Any ->
-           {stop, {protocol_error, Any}}
-    end.
-
-setup(StateData, Params) ->
-    %% Receive startup messages until ReadyForQuery
-    Sock = StateData#state.socket,
-    AsBin = StateData#state.as_binary,
-    {ok, Code, Package} = recv_msg(Sock, 5000),
-    {ok, Pair} = decode_packet(Code, Package, AsBin),
-    case Pair of
-       %% BackendKeyData, necessary for issuing cancel requests
-       {backend_key_data, {Pid, Secret}} ->
-           Params1 = [{secret, {Pid, Secret}} | Params],
-           setup(StateData, Params1);
-       %% ParameterStatus, a key-value pair.
-       {parameter_status, {Key, Value}} ->
-           Params1 = [{{parameter, Key}, Value} | Params],
-           setup(StateData, Params1);
-       %% Error message, with a sequence of <<Code:8/integer, String, 0>>
-       %% of error descriptions. Code==0 terminates the Reason.
-       {error_message, Message} ->
-           gen_tcp:close(Sock),
-           {stop, {error_response, Message}};
-       %% Notice Response, with a sequence of <<Code:8/integer, String,0>>
-       %% identified fields. Code==0 terminates the Notice.
-       {notice_response, Notice} ->
-           deliver(StateData, {pgsql_notice, Notice}),
-           setup(StateData, Params);
-       %% Ready for Query, backend is ready for a new query cycle
-       {ready_for_query, _Status} ->
-           connected(StateData#state{params = Params}, Sock);
-       Any ->
-           {stop, {unknown_setup, Any}}
-    end.
-
-%% Connected state. Can now start to push messages
-%% between frontend and backend. But first some setup.
-connected(StateData, Sock) ->
-    %% Protocol unwrapping process. Factored out to make future
-    %% SSL and unix domain support easier. Store process under
-    %% 'socket' in the process dictionary.
-    AsBin = StateData#state.as_binary,
-    {ok, Unwrapper} = pgsql_tcp:start_link(Sock, self(), AsBin),
-    ok = gen_tcp:controlling_process(Sock, Unwrapper),
-
-    %% Lookup oid to type names and store them in a dictionary under
-    %% 'oidmap' in the process dictionary.
-    Packet = encode_message(squery, "SELECT oid, typname FROM pg_type"),
-    ok = send(Sock, Packet),
-    {ok, [{_, _ColDesc, Rows}]} = process_squery([], AsBin),
-    Rows1 = lists:map(fun ([CodeS, NameS]) ->
-                             Code = to_integer(CodeS),
-                             Name = to_atom(NameS),
-                             {Code, Name}
-                     end,
-                     Rows),
-    OidMap = dict:from_list(Rows1),
-
-    {ok, StateData#state{oidmap = OidMap}}.
-
-
-handle_call(terminate, _From, State) ->
-    Sock = State#state.socket,
-    Packet = encode_message(terminate, []),
-    ok = send(Sock, Packet),
-    gen_tcp:close(Sock),
-    Reply = ok,
-    {stop, normal, Reply, State};
-
-%% Simple query
-handle_call({squery, Query}, _From, State) ->
-    Sock = State#state.socket,
-    AsBin = State#state.as_binary,
-    Packet = encode_message(squery, Query),
-    ok = send(Sock, Packet),
-    {ok, Result} = process_squery([], AsBin),
-    case lists:keymember(error, 1, Result) of
-       true ->
-           RBPacket = encode_message(squery, "ROLLBACK"),
-           ok = send(Sock, RBPacket),
-           {ok, _RBResult} = process_squery([], AsBin);
-       _ ->
-           ok
-    end,
-    Reply = {ok, Result},
-    {reply, Reply, State};
-
-%% Extended query
-%% simplistic version using the unnammed prepared statement and portal.
-handle_call({equery, {Query, Params}}, _From, State) ->
-    Sock = State#state.socket,
-    ParseP =    encode_message(parse, {"", Query, []}),
-    BindP =     encode_message(bind,  {"", "", Params, [binary]}),
-    DescribeP = encode_message(describe, {portal, ""}),
-    ExecuteP =  encode_message(execute,  {"", 0}),
-    SyncP =     encode_message(sync, []),
-    ok = send(Sock, [ParseP, BindP, DescribeP, ExecuteP, SyncP]),
-
-    {ok, Command, Desc, Status, Logs} = process_equery(State, []),
-
-    OidMap = State#state.oidmap,
-    NameTypes = lists:map(fun({Name, _Format, _ColNo, Oid, _, _, _}) ->
-                                 {Name, dict:fetch(Oid, OidMap)}
-                         end,
-                         Desc),
-    Reply = {ok, Command, Status, NameTypes, Logs},
-    {reply, Reply, State};
-
-%% Prepare a statement, so it can be used for queries later on.
-handle_call({prepare, {Name, Query}}, _From, State) ->
-    Sock = State#state.socket,
-    send_message(Sock, parse, {Name, Query, []}),
-    send_message(Sock, describe, {prepared_statement, Name}),
-    send_message(Sock, sync, []),
-    {ok, State, ParamDesc, ResultDesc} = process_prepare({[], []}),
-    OidMap = State#state.oidmap,
-    ParamTypes =
-       lists:map(fun (Oid) -> dict:fetch(Oid, OidMap) end, ParamDesc),
-    ResultNameTypes = lists:map(fun ({ColName, _Format, _ColNo, Oid, _, _, _}) ->
-                                       {ColName, dict:fetch(Oid, OidMap)}
-                               end,
-                               ResultDesc),
-    Reply = {ok, State, ParamTypes, ResultNameTypes},
-    {reply, Reply, State};
-
-%% Close a prepared statement.
-handle_call({unprepare, Name}, _From, State) ->
-    Sock = State#state.socket,
-    send_message(Sock, close, {prepared_statement, Name}),
-    send_message(Sock, sync, []),
-    {ok, _Status} = process_unprepare(),
-    Reply = ok,
-    {reply, Reply, State};
-
-%% Execute a prepared statement
-handle_call({execute, {Name, Params}}, _From, State) ->
-    Sock = State#state.socket,
-    %%io:format("execute: ~p ~p ~n", [Name, Params]),
-    begin % Issue first requests for the prepared statement.
-       BindP     = encode_message(bind, {"", Name, Params, [binary]}),
-       DescribeP = encode_message(describe, {portal, ""}),
-       ExecuteP  = encode_message(execute, {"", 0}),
-       FlushP    = encode_message(flush, []),
-       ok = send(Sock, [BindP, DescribeP, ExecuteP, FlushP])
-    end,
-    receive
-       {pgsql, {bind_complete, _}} -> % Bind reply first.
-           %% Collect response to describe message,
-           %% which gives a hint of the rest of the messages.
-           {ok, Command, Result} = process_execute(State, Sock),
-
-           begin % Close portal and end extended query.
-               CloseP = encode_message(close, {portal, ""}),
-               SyncP  = encode_message(sync, []),
-               ok = send(Sock, [CloseP, SyncP])
-           end,
-           receive
-               %% Collect response to close message.
-               {pgsql, {close_complete, _}} ->
-                   receive
-                       %% Collect response to sync message.
-                       {pgsql, {ready_for_query, _Status}} ->
-                           %%io:format("execute: ~p ~p ~p~n",
-                           %%        [Status, Command, Result]),
-                           Reply = {ok, {Command, Result}},
-                           {reply, Reply, State};
-                       {pgsql, Unknown} ->
-                           {stop, Unknown, {error, Unknown}, State}
-                   end;
-               {pgsql, Unknown} ->
-                   {stop, Unknown, {error, Unknown}, State}
-           end;
-       {pgsql, Unknown} ->
-           {stop, Unknown, {error, Unknown}, State}
-    end;
-
-handle_call(_Request, _From, State) ->
-    Reply = ok,
-    {reply, Reply, State}.
-
-
-handle_cast(_Msg, State) ->
-    {noreply, State}.
-
-
-code_change(_OldVsn, State, _Extra) ->
-    {ok, State}.
-
-
-%% Socket closed or socket error messages.
-handle_info({socket, _Sock, Condition}, State) ->
-    {stop, {socket, Condition}, State};
-handle_info(_Info, State) ->
-    {noreply, State}.
-
-
-terminate(_Reason, _State) ->
-    ok.
-
-
-deliver(State, Message) ->
-    DriverPid = State#state.driver,
-    DriverPid ! Message.
-
-%% In the process_squery state we collect responses until the backend is
-%% done processing.
-process_squery(Log, AsBin) ->
-    receive
-       {pgsql, {row_description, Cols}} ->
-           {ok, Command, Rows} = process_squery_cols([], AsBin),
-           process_squery([{Command, Cols, Rows}|Log], AsBin);
-       {pgsql, {command_complete, Command}} ->
-           process_squery([Command|Log], AsBin);
-       {pgsql, {ready_for_query, _Status}} ->
-           {ok, lists:reverse(Log)};
-       {pgsql, {error_message, Error}} ->
-           process_squery([{error, Error}|Log], AsBin);
-       {pgsql, _Any} ->
-           process_squery(Log, AsBin)
-    end.
-process_squery_cols(Log, AsBin) ->
-    receive
-       {pgsql, {data_row, Row}} ->
-           process_squery_cols(
-             [lists:map(
-                fun(null) ->
-                        null;
-                    (R) when AsBin == true ->
-                         R;
-                   (R) ->
-                        binary_to_list(R)
-                end, Row) | Log], AsBin);
-       {pgsql, {command_complete, Command}} ->
-            {ok, Command, lists:reverse(Log)}
-    end.
-
-process_equery(State, Log) ->
-    receive
-       %% Consume parse and bind complete messages when waiting for the first
-       %% first row_description message. What happens if the equery doesnt
-       %% return a result set?
-       {pgsql, {parse_complete, _}} ->
-           process_equery(State, Log);
-       {pgsql, {bind_complete, _}} ->
-           process_equery(State, Log);
-       {pgsql, {row_description, Descs}} ->
-           OidMap = State#state.oidmap,
-           {ok, Descs1} = pgsql_util:decode_descs(OidMap, Descs),
-           process_equery_datarow(Descs1, Log, {undefined, Descs, undefined});
-       {pgsql, Any} ->
-           process_equery(State, [Any|Log])
-    end.
-
-process_equery_datarow(Types, Log, Info={Command, Desc, Status}) ->
-    receive
-       %%
-       {pgsql, {command_complete, Command1}} ->
-           process_equery_datarow(Types, Log, {Command1, Desc, Status});
-       {pgsql, {ready_for_query, Status1}} ->
-           {ok, Command, Desc, Status1, lists:reverse(Log)};
-       {pgsql, {data_row, Row}} ->
-           {ok, DecodedRow} = pgsql_util:decode_row(Types, Row),
-           process_equery_datarow(Types, [DecodedRow|Log], Info);
-       {pgsql, Any} ->
-           process_equery_datarow(Types, [Any|Log], Info)
-    end.
-
-process_prepare(Info={ParamDesc, ResultDesc}) ->
-    receive
-       {pgsql, {no_data, _}} ->
-           process_prepare({ParamDesc, []});
-       {pgsql, {parse_complete, _}} ->
-           process_prepare(Info);
-       {pgsql, {parameter_description, Oids}} ->
-           process_prepare({Oids, ResultDesc});
-       {pgsql, {row_description, Desc}} ->
-           process_prepare({ParamDesc, Desc});
-       {pgsql, {ready_for_query, Status}} ->
-           {ok, Status, ParamDesc, ResultDesc};
-       {pgsql, Any} ->
-           io:format("process_prepare: ~p~n", [Any]),
-           process_prepare(Info)
-    end.
-
-process_unprepare() ->
-    receive
-       {pgsql, {ready_for_query, Status}} ->
-           {ok, Status};
-       {pgsql, {close_complate, []}} ->
-           process_unprepare();
-       {pgsql, Any} ->
-           io:format("process_unprepare: ~p~n", [Any]),
-           process_unprepare()
-    end.
-
-process_execute(State, Sock) ->
-    %% Either the response begins with a no_data or a row_description
-    %% Needs to return {ok, Status, Result}
-    %% where Result = {Command, ...}
-    receive
-       {pgsql, {no_data, _}} ->
-           {ok, _Command, _Result} = process_execute_nodata();
-       {pgsql, {row_description, Descs}} ->
-           OidMap = State#state.oidmap,
-           {ok, Types} = pgsql_util:decode_descs(OidMap, Descs),
-           {ok, _Command, _Result} =
-               process_execute_resultset(Sock, Types, []);
-       {pgsql, Unknown} ->
-           exit(Unknown)
-    end.
-
-process_execute_nodata() ->
-    receive
-       {pgsql, {command_complete, Cmd}} ->
-            Command = if is_binary(Cmd) ->
-                              binary_to_list(Cmd);
-                         true ->
-                              Cmd
-                      end,
-           case Command of
-               "INSERT "++Rest ->
-                   {ok, [{integer, _, _Table},
-                         {integer, _, NRows}], _} = erl_scan:string(Rest),
-                   {ok, 'INSERT', NRows};
-               "SELECT" ->
-                   {ok, 'SELECT', should_not_happen};
-               "DELETE "++Rest ->
-                   {ok, [{integer, _, NRows}], _} =
-                       erl_scan:string(Rest),
-                   {ok, 'DELETE', NRows};
-               Any ->
-                   {ok, nyi, Any}
-           end;
-
-       {pgsql, Unknown} ->
-           exit(Unknown)
-    end.
-process_execute_resultset(Sock, Types, Log) ->
-    receive
-       {pgsql, {command_complete, Command}} ->
-           {ok, to_atom(Command), lists:reverse(Log)};
-       {pgsql, {data_row, Row}} ->
-           {ok, DecodedRow} = pgsql_util:decode_row(Types, Row),
-           process_execute_resultset(Sock, Types, [DecodedRow|Log]);
-       {pgsql, {portal_suspended, _}} ->
-           throw(portal_suspended);
-       {pgsql, Any} ->
-           %%process_execute_resultset(Types, [Any|Log])
-           exit(Any)
-    end.
-
-%% With a message type Code and the payload Packet apropriate
-%% decoding procedure can proceed.
-decode_packet(Code, Packet, AsBin) ->
-    Ret = fun(CodeName, Values) -> {ok, {CodeName, Values}} end,
-    case Code of
-       ?PG_ERROR_MESSAGE ->
-           Message = pgsql_util:errordesc(Packet, AsBin),
-           Ret(error_message, Message);
-       ?PG_EMPTY_RESPONSE ->
-           Ret(empty_response, []);
-       ?PG_ROW_DESCRIPTION ->
-           <<_Columns:16/integer, ColDescs/binary>> = Packet,
-           Descs = coldescs(ColDescs, [], AsBin),
-           Ret(row_description, Descs);
-       ?PG_READY_FOR_QUERY ->
-           <<State:8/integer>> = Packet,
-           case State of
-               $I ->
-                   Ret(ready_for_query, idle);
-               $T ->
-                   Ret(ready_for_query, transaction);
-               $E ->
-                   Ret(ready_for_query, failed_transaction)
-           end;
-       ?PG_COMMAND_COMPLETE ->
-           {Task, _} = to_string(Packet, AsBin),
-           Ret(command_complete, Task);
-       ?PG_DATA_ROW ->
-           <<NumberCol:16/integer, RowData/binary>> = Packet,
-           ColData = datacoldescs(NumberCol, RowData, []),
-           Ret(data_row, ColData);
-       ?PG_BACKEND_KEY_DATA ->
-           <<Pid:32/integer, Secret:32/integer>> = Packet,
-           Ret(backend_key_data, {Pid, Secret});
-       ?PG_PARAMETER_STATUS ->
-           {Key, Value} = split_pair(Packet, AsBin),
-           Ret(parameter_status, {Key, Value});
-       ?PG_NOTICE_RESPONSE ->
-           Ret(notice_response, []);
-       ?PG_AUTHENTICATE ->
-           <<AuthMethod:32/integer, Salt/binary>> = Packet,
-           Ret(authenticate, {AuthMethod, Salt});
-       ?PG_PARSE_COMPLETE ->
-           Ret(parse_complete, []);
-       ?PG_BIND_COMPLETE ->
-           Ret(bind_complete, []);
-       ?PG_PORTAL_SUSPENDED ->
-           Ret(portal_suspended, []);
-       ?PG_CLOSE_COMPLETE ->
-           Ret(close_complete, []);
-       $t ->
-           <<_NParams:16/integer, OidsP/binary>> = Packet,
-           Oids = pgsql_util:oids(OidsP, []),
-           Ret(parameter_description, Oids);
-       ?PG_NO_DATA ->
-           Ret(no_data, []);
-       _Any ->
-           Ret(unknown, [Code])
-    end.
-
-send_message(Sock, Type, Values) ->
-    %%io:format("send_message:~p~n", [{Type, Values}]),
-    Packet = encode_message(Type, Values),
-    ok = send(Sock, Packet).
-
-%% Add header to a message.
-encode(Code, Packet) ->
-    Len = size(Packet) + 4,
-    <<Code:8/integer, Len:4/integer-unit:8, Packet/binary>>.
-
-%% Encode a message of a given type.
-encode_message(pass_plain, Password) ->
-               Pass = pgsql_util:pass_plain(Password),
-               encode($p, Pass);
-encode_message(pass_md5, {User, Password, Salt}) ->
-               Pass = pgsql_util:pass_md5(User, Password, Salt),
-               encode($p, Pass);
-encode_message(terminate, _) ->
-    encode($X, <<>>);
-encode_message(squery, Query) -> % squery as in simple query.
-    encode($Q, string(Query));
-encode_message(close, {Object, Name}) ->
-    Type = case Object of prepared_statement -> $S; portal -> $P end,
-    String = string(Name),
-    encode($C, <<Type/integer, String/binary>>);
-encode_message(describe, {Object, Name}) ->
-    ObjectP = case Object of prepared_statement -> $S; portal -> $P end,
-    NameP = string(Name),
-    encode($D, <<ObjectP:8/integer, NameP/binary>>);
-encode_message(flush, _) ->
-    encode($H, <<>>);
-encode_message(parse, {Name, Query, _Oids}) ->
-    StringName = string(Name),
-    StringQuery = string(Query),
-    encode($P, <<StringName/binary, StringQuery/binary, 0:16/integer>>);
-encode_message(bind, {NamePortal, NamePrepared,
-                     Parameters, ResultFormats}) ->
-    PortalP = string(NamePortal),
-    PreparedP = string(NamePrepared),
-
-    ParamFormatsList = lists:map(
-                        fun (Bin) when is_binary(Bin) -> <<1:16/integer>>;
-                            (_Text) -> <<0:16/integer>> end,
-                        Parameters),
-    ParamFormatsP = erlang:list_to_binary(ParamFormatsList),
-
-    NParameters = length(Parameters),
-    ParametersList = lists:map(
-                      fun (null) ->
-                              Minus = -1,
-                              <<Minus:32/integer>>;
-                          (Bin) when is_binary(Bin) ->
-                              Size = size(Bin),
-                              <<Size:32/integer, Bin/binary>>;
-                          (Integer) when is_integer(Integer) ->
-                              List = integer_to_list(Integer),
-                              Bin = list_to_binary(List),
-                              Size = size(Bin),
-                              <<Size:32/integer, Bin/binary>>;
-                          (Text) ->
-                              Bin = list_to_binary(Text),
-                              Size = size(Bin),
-                              <<Size:32/integer, Bin/binary>>
-                      end,
-                      Parameters),
-    ParametersP = erlang:list_to_binary(ParametersList),
-
-    NResultFormats = length(ResultFormats),
-    ResultFormatsList = lists:map(
-                         fun (binary) -> <<1:16/integer>>;
-                             (text) ->   <<0:16/integer>> end,
-                         ResultFormats),
-    ResultFormatsP = erlang:list_to_binary(ResultFormatsList),
-
-    %%io:format("encode bind: ~p~n", [{PortalP, PreparedP,
-       %%                           NParameters, ParamFormatsP,
-       %%                           NParameters, ParametersP,
-       %%                           NResultFormats, ResultFormatsP}]),
-    encode($B, <<PortalP/binary, PreparedP/binary,
-               NParameters:16/integer, ParamFormatsP/binary,
-               NParameters:16/integer, ParametersP/binary,
-               NResultFormats:16/integer, ResultFormatsP/binary>>);
-encode_message(execute, {Portal, Limit}) ->
-    String = string(Portal),
-    encode($E, <<String/binary, Limit:32/integer>>);
-encode_message(sync, _) ->
-    encode($S, <<>>).
diff --git a/src/pgsql/pgsql_tcp.erl b/src/pgsql/pgsql_tcp.erl
deleted file mode 100644 (file)
index 2174025..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-%%% File    : pgsql_tcp.erl
-%%% Author  : Blah <cos@local>
-%%% Description : Unwrapping of TCP line protocol packages to postgres messages.
-%%% Created : 22 Jul 2005
-
--module(pgsql_tcp).
-
--behaviour(gen_server).
-
--export([start/3, start_link/3]).
-
-%% gen_server callbacks
--export([init/1,
-        handle_call/3,
-        handle_cast/2,
-        code_change/3,
-        handle_info/2,
-        terminate/2]).
-
--record(state, {socket, protopid, buffer, as_binary}).
-
-start(Sock, ProtoPid, AsBin) ->
-    gen_server:start(?MODULE, [Sock, ProtoPid, AsBin], []).
-
-start_link(Sock, ProtoPid, AsBin) ->
-    gen_server:start_link(?MODULE, [Sock, ProtoPid, AsBin], []).
-
-init([Sock, ProtoPid, AsBin]) ->
-    inet:setopts(Sock, [{active, once}]),
-    {ok, #state{socket = Sock, protopid = ProtoPid,
-                buffer = <<>>, as_binary = AsBin}}.
-
-handle_call(_Request, _From, State) ->
-    Reply = ok,
-    {reply, Reply, State}.
-
-handle_cast(_Msg, State) ->
-    {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) ->
-    {ok, State}.
-
-handle_info({tcp, Sock, Bin},
-           #state{socket = Sock,
-                  protopid = ProtoPid,
-                   as_binary = AsBin,
-                  buffer = Buffer} = State) ->
-    {ok, Rest} = process_buffer(ProtoPid, AsBin, <<Buffer/binary, Bin/binary>>),
-    inet:setopts(Sock, [{active, once}]),
-    {noreply, State#state{buffer = Rest}};
-handle_info({tcp_closed, Sock},
-           #state{socket = Sock,
-                  protopid = ProtoPid} = State) ->
-    io:format("Sock closed~n", []),
-    ProtoPid ! {socket, Sock, closed},
-    {stop, tcp_close, State};
-handle_info({tcp_error, Sock, Reason},
-           #state{socket = Sock,
-                  protopid = ProtoPid} = State) ->
-    io:format("Sock error~n", []),
-    ProtoPid ! {socket, Sock, {error, Reason}},
-    {stop, tcp_error, State};
-handle_info(_Info, State) ->
-    {noreply, State}.
-
-
-terminate(_Reason, _State) ->
-    ok.
-
-
-%% Given a binary that begins with a proper message header the binary
-%% will be processed for each full message it contains, and it will
-%% return any trailing incomplete messages.
-process_buffer(ProtoPid, AsBin,
-               Bin = <<Code:8/integer, Size:4/integer-unit:8, Rest/binary>>) ->
-    Payload = Size - 4,
-    if
-       size(Rest) >= Payload ->
-           <<Packet:Payload/binary, Rest1/binary>> = Rest,
-           {ok, Message} = pgsql_proto:decode_packet(Code, Packet, AsBin),
-           ProtoPid ! {pgsql, Message},
-           process_buffer(ProtoPid, AsBin, Rest1);
-       true ->
-           {ok, Bin}
-    end;
-process_buffer(_ProtoPid, _AsBin, Bin) when is_binary(Bin) ->
-    {ok, Bin}.
-
diff --git a/src/pgsql/pgsql_util.erl b/src/pgsql/pgsql_util.erl
deleted file mode 100644 (file)
index d562f29..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-%%% File    : pgsql_util.erl
-%%% Author  : Christian Sunesson
-%%% Description : utility functions used in implementation of 
-%%%               postgresql driver.
-%%% Created : 11 May 2005 by Blah <cos@local>
-
--module(pgsql_util).
-
-%% Key-Value handling
--export([option/3]).
-
-%% Networking
--export([socket/1]).
--export([send/2, send_int/2, send_msg/3]).
--export([recv_msg/2, recv_msg/1, recv_byte/2, recv_byte/1]).
-
-%% Protocol packing
--export([string/1, make_pair/2, split_pair/2]).
--export([split_pair_rec/2]).
--export([count_string/1, to_string/2]).
--export([oids/2, coldescs/3, datacoldescs/3]).
--export([decode_row/3, decode_descs/2]).
--export([errordesc/2]).
--export([to_integer/1, to_atom/1]).
-
--export([zip/2]).
-
-%% Constructing authentication messages.
--export([pass_plain/1, pass_md5/3]).
--import(erlang, [md5/1]).
--export([hexlist/2]).
-
-%% Lookup key in a plist stored in process dictionary under 'options'.
-%% Default is returned if there is no value for Key in the plist.
-option(Opts, Key, Default) ->
-    case proplists:get_value(Key, Opts, Default) of
-       Default ->
-           Default;
-       Value when is_binary(Value) ->
-           binary_to_list(Value);
-        Value ->
-            Value
-    end.
-
-
-%% Open a TCP connection
-socket({tcp, Host, Port}) ->
-    gen_tcp:connect(Host, Port, [{active, false}, binary, {packet, raw}], 5000).
-
-send(Sock, Packet) ->
-    gen_tcp:send(Sock, Packet).
-send_int(Sock, Int) ->
-    Packet = <<Int:32/integer>>,
-    gen_tcp:send(Sock, Packet).
-
-send_msg(Sock, Code, Packet) when is_binary(Packet) ->
-    Len = size(Packet) + 4,
-    Msg = <<Code:8/integer, Len:4/integer-unit:8, Packet/binary>>,
-    gen_tcp:send(Sock, Msg).
-
-recv_msg(Sock, Timeout) ->
-    {ok, Head} = gen_tcp:recv(Sock, 5, Timeout),
-    <<Code:8/integer, Size:4/integer-unit:8>> = Head,
-    %%io:format("Code: ~p, Size: ~p~n", [Code, Size]),
-    if 
-       Size > 4 ->
-           {ok, Packet} = gen_tcp:recv(Sock, Size-4, Timeout),
-           {ok, Code, Packet};
-       true ->
-           {ok, Code, <<>>}
-    end.
-recv_msg(Sock) ->
-    recv_msg(Sock, infinity).
-
-
-recv_byte(Sock) ->
-    recv_byte(Sock, infinity).
-recv_byte(Sock, Timeout) ->
-    case gen_tcp:recv(Sock, 1, Timeout) of
-       {ok, <<Byte:1/integer-unit:8>>} ->
-           {ok, Byte};
-       E={error, _Reason} ->
-           throw(E)
-    end.
-
-%% Convert String to binary
-string(String) when is_list(String) ->
-    Bin = list_to_binary(String),
-    <<Bin/binary, 0/integer>>;
-string(Bin) when is_binary(Bin) ->
-    <<Bin/binary, 0/integer>>.
-
-%%% Two zero terminated strings.
-make_pair(Key, Value) when is_atom(Key) ->
-    make_pair(atom_to_list(Key), Value);
-make_pair(Key, Value) when is_atom(Value) ->
-    make_pair(Key, atom_to_list(Value));
-make_pair(Key, Value) when is_list(Key), is_list(Value) ->
-    BinKey = list_to_binary(Key),
-    BinValue = list_to_binary(Value),
-    make_pair(BinKey, BinValue);
-make_pair(Key, Value) when is_binary(Key), is_binary(Value) ->
-    <<Key/binary, 0/integer, 
-     Value/binary, 0/integer>>.
-
-split_pair(Bin, AsBin) when is_binary(Bin) ->
-    split_pair(binary_to_list(Bin), AsBin);
-split_pair(Str, AsBin)  ->
-    split_pair_rec(Str, norec, AsBin).
-
-split_pair_rec(Bin, AsBin) when is_binary(Bin) ->
-    split_pair_rec(binary_to_list(Bin), AsBin);
-split_pair_rec(Arg, AsBin)  ->
-    split_pair_rec(Arg,[], AsBin).
-
-split_pair_rec([], Acc, _AsBin) ->
-    lists:reverse(Acc);
-split_pair_rec([0], Acc, _AsBin) ->
-    lists:reverse(Acc);
-split_pair_rec(S, Acc, AsBin) ->
-    Fun = fun(C) -> C /= 0 end,
-    {K, [0|S1]} = lists:splitwith(Fun, S),
-    {V, [0|Tail]} = lists:splitwith(Fun, S1),
-    {Key, Value} = if AsBin ->
-                           {list_to_binary(K), list_to_binary(V)};
-                      true ->
-                           {K, V}
-                   end,
-    case Acc of 
-        norec -> {Key, Value};
-        _ ->
-            split_pair_rec(Tail, [{Key, Value}| Acc], AsBin)
-    end.
-
-
-count_string(Bin) when is_binary(Bin) ->
-    count_string(Bin, 0).
-
-count_string(<<>>, N) ->
-    {N, <<>>};
-count_string(<<0/integer, Rest/binary>>, N) ->
-    {N, Rest};
-count_string(<<_C/integer, Rest/binary>>, N) ->
-    count_string(Rest, N+1).
-
-to_string(Bin, AsBin) when is_binary(Bin) ->    
-    {Count, _} = count_string(Bin, 0),
-    <<String:Count/binary, _/binary>> = Bin,
-    if AsBin ->
-            {String, Count};
-       true ->
-            {binary_to_list(String), Count}
-    end.
-
-oids(<<>>, Oids) ->
-    lists:reverse(Oids);
-oids(<<Oid:32/integer, Rest/binary>>, Oids) ->
-    oids(Rest, [Oid|Oids]).
-    
-coldescs(<<>>, Descs, _AsBin) ->
-    lists:reverse(Descs);
-coldescs(Bin, Descs, AsBin) ->
-    {Name, Count} = to_string(Bin, AsBin),
-    <<_:Count/binary, 0/integer,
-     TableOID:32/integer,
-     ColumnNumber:16/integer,
-     TypeId:32/integer,
-     TypeSize:16/integer-signed,
-     TypeMod:32/integer-signed,
-     FormatCode:16/integer,
-     Rest/binary>> = Bin,
-    Format = case FormatCode of 
-                0 -> text; 
-                1 -> binary 
-            end,
-    Desc = {Name, Format, ColumnNumber, 
-           TypeId, TypeSize, TypeMod, 
-           TableOID},
-    coldescs(Rest, [Desc|Descs], AsBin).
-
-datacoldescs(N, <<16#ffffffff:32, Rest/binary>>, Descs) when N >= 0 ->
-    datacoldescs(N-1, Rest, [null|Descs]);
-datacoldescs(N, 
-            <<Len:32/integer, Data:Len/binary, Rest/binary>>, 
-            Descs) when N >= 0 ->
-    datacoldescs(N-1, Rest, [Data|Descs]);
-datacoldescs(_N, _, Descs) ->
-    lists:reverse(Descs).
-
-decode_descs(OidMap, Cols) ->
-    decode_descs(OidMap, Cols, []).
-decode_descs(_OidMap, [], Descs) ->
-    {ok, lists:reverse(Descs)};
-decode_descs(OidMap, [Col|ColTail], Descs) ->
-    {Name, Format, ColNumber, Oid, _, _, _} = Col,
-    OidName = dict:fetch(Oid, OidMap),
-    decode_descs(OidMap, ColTail, [{Name, Format, ColNumber, OidName, [], [], []}|Descs]).
-
-decode_row(Types, Values, AsBin) ->
-    decode_row(Types, Values, [], AsBin).
-decode_row([], [], Out, _AsBin) ->
-    {ok, lists:reverse(Out)};
-decode_row([Type|TypeTail], [Value|ValueTail], Out0, AsBin) ->
-    Out1 = decode_col(Type, Value, AsBin),
-    decode_row(TypeTail, ValueTail, [Out1|Out0], AsBin).
-
-decode_col({_, text, _, _, _, _, _}, Value, AsBin) ->
-    if AsBin -> Value;
-       true -> binary_to_list(Value)
-    end;
-decode_col({_Name, _Format, _ColNumber, varchar, _Size, _Modifier, _TableOID}, Value, AsBin) ->
-    if AsBin -> Value;
-       true -> binary_to_list(Value)
-    end;
-decode_col({_Name, _Format, _ColNumber, int4, _Size, _Modifier, _TableOID}, Value, _AsBin) ->
-    <<Int4:32/integer>> = Value,
-    Int4;
-decode_col({_Name, _Format, _ColNumber, Oid, _Size, _Modifier, _TableOID}, Value, _AsBin) ->
-    {Oid, Value}.
-
-errordesc(Bin, AsBin) ->
-    errordesc(Bin, [], AsBin).
-
-errordesc(<<0/integer, _Rest/binary>>, Lines, _AsBin) ->
-    lists:reverse(Lines);
-errordesc(<<Code/integer, Rest/binary>>, Lines, AsBin) ->
-    {String, Count} = to_string(Rest, AsBin),
-    <<_:Count/binary, 0, Rest1/binary>> = Rest,
-    Msg = case Code of 
-             $S ->
-                 {severity, to_atom(String)};
-             $C ->
-                 {code, String};
-             $M ->
-                 {message, String};
-             $D ->
-                 {detail, String};
-             $H ->
-                 {hint, String};
-             $P ->
-                 {position, to_integer(String)};
-             $p ->
-                 {internal_position, to_integer(String)};
-             $W ->
-                 {where, String};
-             $F ->
-                 {file, String};
-             $L ->
-                 {line, to_integer(String)};
-             $R ->
-                 {routine, String};
-             Unknown ->
-                 {Unknown, String}
-         end,
-    errordesc(Rest1, [Msg|Lines]).
-
-%%% Zip two lists together
-zip(List1, List2) ->
-    zip(List1, List2, []).
-zip(List1, List2, Result) when List1 =:= []; 
-                              List2 =:= [] ->
-    lists:reverse(Result);
-zip([H1|List1], [H2|List2], Result) ->
-    zip(List1, List2, [{H1, H2}|Result]).
-
-%%% Authentication utils
-
-pass_plain(Password) ->
-       Pass = [Password, 0],
-       list_to_binary(Pass). 
-
-%% MD5 authentication patch from
-%%    Juhani Rankimies <juhani@juranki.com>
-%% (patch slightly rewritten, new bugs are mine :] /Christian Sunesson)
-
-%%
-%% MD5(MD5(password + user) + salt)
-%%
-
-pass_md5(User, Password, Salt) ->
-    Digest = hex(md5([Password, User])),
-    Encrypt = hex(md5([Digest, Salt])),
-    Pass = ["md5", Encrypt, 0],
-    list_to_binary(Pass).
-
-to_integer(B) when is_binary(B) ->
-    to_integer(binary_to_list(B));
-to_integer(S) ->
-    list_to_integer(S).
-
-to_atom(B) when is_binary(B) ->
-    to_atom(binary_to_list(B));
-to_atom(S) ->
-    list_to_atom(S).
-
-hex(B) when is_binary(B) ->
-    hexlist(binary_to_list(B), []).
-
-hexlist([], Acc) ->
-    lists:reverse(Acc);
-hexlist([N|Rest], Acc) ->
-    HighNibble = (N band 16#f0) bsr 4,
-    LowNibble = (N band 16#0f),
-    hexlist(Rest, [hexdigit(LowNibble), hexdigit(HighNibble)|Acc]).
-
-hexdigit(0) -> $0;
-hexdigit(1) -> $1;
-hexdigit(2) -> $2;
-hexdigit(3) -> $3;
-hexdigit(4) -> $4;
-hexdigit(5) -> $5;
-hexdigit(6) -> $6;
-hexdigit(7) -> $7;
-hexdigit(8) -> $8;
-hexdigit(9) -> $9;
-hexdigit(10) -> $a;
-hexdigit(11) -> $b;
-hexdigit(12) -> $c;
-hexdigit(13) -> $d;
-hexdigit(14) -> $e;
-hexdigit(15) -> $f.
diff --git a/src/sha.erl b/src/sha.erl
deleted file mode 100644 (file)
index 28df507..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : sha.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : 
-%%% Created : 20 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(sha).
-
--author('alexey@process-one.net').
-
--export([start/0, sha/1, sha1/1, sha224/1, sha256/1,
-        sha384/1, sha512/1, to_hexlist/1]).
-
--ifdef(HAVE_MD2).
-
--export([md2/1]).
-
--endif.
-
--include("ejabberd.hrl").
-
--define(DRIVER, sha_drv).
-
-start() ->
-    crypto:start(),
-    Res = case erl_ddll:load_driver(ejabberd:get_so_path(),
-                                   ?DRIVER)
-             of
-           ok -> ok;
-           {error, already_loaded} -> ok;
-           Err -> Err
-         end,
-    case Res of
-      ok ->
-         Port = open_port({spawn, atom_to_list(?DRIVER)},
-                          [binary]),
-         register(?DRIVER, Port);
-      {error, Reason} ->
-         ?CRITICAL_MSG("unable to load driver '~s': ~s",
-                       [driver_path(), erl_ddll:format_error(Reason)])
-    end.
-
-digit_to_xchar(D) when (D >= 0) and (D < 10) -> D + 48;
-digit_to_xchar(D) -> D + 87.
-
--spec sha(binary()) -> binary().
-
-sha(Text) ->
-    Bin = crypto:sha(Text),
-    to_hexlist(Bin).
-
--spec to_hexlist(binary()) -> binary().
-
-to_hexlist(Bin) ->
-    iolist_to_binary(lists:reverse(ints_to_rxstr(binary_to_list(Bin), []))).
-
-ints_to_rxstr([], Res) -> Res;
-ints_to_rxstr([N | Ns], Res) ->
-    ints_to_rxstr(Ns,
-                 [digit_to_xchar(N rem 16), digit_to_xchar(N div 16)
-                  | Res]).
-
--spec sha1(binary()) -> binary().
--spec sha224(binary()) -> binary().
--spec sha256(binary()) -> binary().
--spec sha384(binary()) -> binary().
--spec sha512(binary()) -> binary().
-
-sha1(Text) -> crypto:sha(Text).
-
-sha224(Text) -> erlang:port_control(?DRIVER, 224, Text).
-
-sha256(Text) -> erlang:port_control(?DRIVER, 256, Text).
-
-sha384(Text) -> erlang:port_control(?DRIVER, 384, Text).
-
-sha512(Text) -> erlang:port_control(?DRIVER, 512, Text).
-
--ifdef(HAVE_MD2).
-
--spec md2(binary()) -> binary().
-
-md2(Text) -> erlang:port_control(?DRIVER, 2, Text).
-
--endif.
-
-driver_path() ->
-    Suffix = case os:type() of
-              {win32, _} -> ".dll";
-              _ -> ".so"
-            end,
-    filename:join(ejabberd:get_so_path(),
-                 atom_to_list(?DRIVER) ++ Suffix).
index c86acd701c1983a05e061f8e2fc162ab4d9c9326..37c1a30c9ff1ab5e0156d2fb760aa62945907c9d 100644 (file)
@@ -31,6 +31,7 @@
 -export([new/1, new1/1, update/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -record(maxrate, {maxrate  = 0   :: integer(),
                   lastrate = 0.0 :: float(),
diff --git a/src/stringprep/Makefile.in b/src/stringprep/Makefile.in
deleted file mode 100644 (file)
index 7c4997d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-ifeq ($(shell uname),Darwin)
-    DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-endif
-ifeq ($(shell uname),SunOs)
-    DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
-endif
-
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-ERLSHLIBS = ../stringprep_drv.so
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS) $(ERLSHLIBS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-#all:  $(ERLSHLIBS)
-#      erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
-
-$(ERLSHLIBS):  ../%.so:        %.c uni_data.c uni_norm.c
-       $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) \
-               $(subst ../,,$(subst .so,.c,$@)) $(LIBS) \
-               $(ERLANG_LIBS) \
-               $(ERLANG_CFLAGS) \
-               -o $@ \
-               $(DYNAMIC_LIB_CFLAGS)
-
-clean:
-       rm -f $(BEAMS) $(ERLSHLIBS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/stringprep/Makefile.win32 b/src/stringprep/Makefile.win32
deleted file mode 100644 (file)
index b044a10..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\stringprep.beam ..\stringprep_sup.beam
-
-SOURCE = stringprep_drv.c
-AUXIL  = uni_data.c uni_norm.c
-OBJECT = stringprep_drv.o
-DLL    = $(OUTDIR)\stringprep_drv.dll
-
-ALL : $(DLL) $(BEAMS)
-
-CLEAN :
-       -@erase $(DLL)
-       -@erase $(OUTDIR)\stringprep_drv.exp
-       -@erase $(OUTDIR)\stringprep_drv.lib
-       -@erase $(OBJECT)
-       -@erase $(BEAMS)
-
-$(OUTDIR)\stringprep.beam : stringprep.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) stringprep.erl
-
-$(OUTDIR)\stringprep_sup.beam : stringprep_sup.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) stringprep_sup.erl
-
-CC=cl.exe
-CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include"
-
-LD=link.exe
-LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
-
-$(DLL) : $(OBJECT)
-       $(LD) $(LD_FLAGS) -out:$@ $<
-
-$(OBJECT) : $(SOURCE) $(AUXIL)
-       $(CC) $(CC_FLAGS) -c -Fo$@ $<
-
diff --git a/src/stringprep/stringprep.erl b/src/stringprep/stringprep.erl
deleted file mode 100644 (file)
index 1b39693..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : stringprep.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : Interface to stringprep_drv
-%%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@proces-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(stringprep).
-
--author('alexey@process-one.net').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0, tolower/1, nameprep/1,
-        nodeprep/1, resourceprep/1]).
-
-%% Internal exports, call-back functions.
--export([init/1, handle_call/3, handle_cast/2,
-        handle_info/2, code_change/3, terminate/2]).
-
--define(STRINGPREP_PORT, stringprep_port).
-
--define(NAMEPREP_COMMAND, 1).
-
--define(NODEPREP_COMMAND, 2).
-
--define(RESOURCEPREP_COMMAND, 3).
-
-start() ->
-    gen_server:start({local, ?MODULE}, ?MODULE, [], []).
-
-start_link() ->
-    gen_server:start_link({local, ?MODULE}, ?MODULE, [],
-                         []).
-
-init([]) ->
-    case erl_ddll:load_driver(ejabberd:get_so_path(),
-                             stringprep_drv)
-       of
-      ok -> ok;
-      {error, already_loaded} -> ok
-    end,
-    Port = open_port({spawn, "stringprep_drv"}, []),
-    register(?STRINGPREP_PORT, Port),
-    {ok, Port}.
-
-%%% --------------------------------------------------------
-%%% The call-back functions.
-%%% --------------------------------------------------------
-
-handle_call(_, _, State) -> {noreply, State}.
-
-handle_cast(_, State) -> {noreply, State}.
-
-handle_info({'EXIT', Port, Reason}, Port) ->
-    {stop, {port_died, Reason}, Port};
-handle_info({'EXIT', _Pid, _Reason}, Port) ->
-    {noreply, Port};
-handle_info(_, State) -> {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
-
-terminate(_Reason, Port) -> Port ! {self, close}, ok.
-
--spec tolower(binary()) -> binary() | error.
-
-tolower(String) -> control(0, String).
-
--spec nameprep(binary()) -> binary() | error.
-
-nameprep(String) -> control(?NAMEPREP_COMMAND, String).
-
--spec nodeprep(binary()) -> binary() | error.
-
-nodeprep(String) -> control(?NODEPREP_COMMAND, String).
-
--spec resourceprep(binary()) -> binary() | error.
-
-resourceprep(String) ->
-    control(?RESOURCEPREP_COMMAND, String).
-
-control(Command, String) ->
-    case port_control(?STRINGPREP_PORT, Command, String) of
-      <<0, _/binary>> -> error;
-      <<1, Res/binary>> -> Res
-    end.
diff --git a/src/stringprep/stringprep_drv.c b/src/stringprep/stringprep_drv.c
deleted file mode 100644 (file)
index cada923..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013   ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <ei.h>
-
-#include "uni_data.c"
-#include "uni_norm.c"
-
-#define NAMEPREP_COMMAND 1
-#define NODEPREP_COMMAND 2
-#define RESOURCEPREP_COMMAND 3
-
-/*
- * R15B changed several driver callbacks to use ErlDrvSizeT and
- * ErlDrvSSizeT typedefs instead of int.
- * This provides missing typedefs on older OTP versions.
- */
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int ErlDrvSizeT;
-typedef int ErlDrvSSizeT;
-#endif
-
-typedef struct {
-      ErlDrvPort port;
-} stringprep_data;
-
-
-static ErlDrvData stringprep_erl_start(ErlDrvPort port, char *buff)
-{
-   stringprep_data* d = (stringprep_data*)driver_alloc(sizeof(stringprep_data));
-   d->port = port;
-
-   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-   
-   return (ErlDrvData)d;
-}
-
-static void stringprep_erl_stop(ErlDrvData handle)
-{
-   driver_free((char*)handle);
-}
-
-
-/* Hangul constants */
-#define SBase 0xAC00
-#define LBase 0x1100
-#define VBase 0x1161
-#define TBase 0x11A7
-#define LCount 19
-#define VCount 21
-#define TCount 28
-#define NCount (VCount * TCount)
-#define SCount (LCount * NCount)
-
-/*
- * "canonical_ordering" and "compose" functions are based on nfkc.c from Gnome
- * library
- */
-
-static void canonical_ordering(int *str, int len)
-{
-   int i, j, t;
-   int last, next;
-
-   last = GetUniCharCClass(str[0]);
-   for (i = 0; i < len - 1; i++)
-   {
-      next = GetUniCharCClass(str[i + 1]);
-      if (next != 0 && last > next)
-      {
-        for (j = i; j >= 0; j--)
-        {
-           if (GetUniCharCClass(str[j]) <= next)
-              break;
-           t = str[j + 1];
-           str[j + 1] = str[j];
-           str[j] = t;
-        }
-        next = last;
-      }
-      last = next;
-   }
-}
-
-
-static int compose(int ch1, int ch2)
-{
-   int info1, info2;
-
-   if (LBase <= ch1 && ch1 < LBase + LCount &&
-       VBase <= ch2 && ch2 < VBase + VCount) {
-      return SBase + ((ch1 - LBase) * VCount + (ch2 - VBase)) * TCount;
-   }
-
-   if (SBase <= ch1 && ch1 < SBase + SCount && ((ch1 - SBase) % TCount) == 0 &&
-       TBase <= ch2 && ch2 < TBase + TCount) {
-      return ch1 + ch2 - TBase;
-   }
-
-   info1 = GetUniCharCompInfo(ch1);
-   if (info1 != -1 && info1 & CompSingleMask) {
-      if (!(info1 & CompSecondMask) &&
-         ch2 == compFirstList[info1 & CompMask][0]) {
-        return compFirstList[info1 & CompMask][1];
-      } else
-        return 0;
-   }
-
-   info2 = GetUniCharCompInfo(ch2);
-   if (info2 != -1 && info2 & CompSingleMask) {
-      if ((info2 & CompSecondMask) &&
-         ch1 == compSecondList[info2 & CompMask][0]) {
-        return compSecondList[info2 & CompMask][1];
-      } else
-        return 0;
-   }
-
-   if (info1 != -1 && info2 != -1 &&
-       !(info1 & CompSecondMask) && (info2 & CompSecondMask))
-      return compBothList[info1][info2 & CompMask];
-   else
-      return 0;
-}
-
-
-#define ADD_UCHAR(ruc)                                                 \
-        if (ruc <= 0x7F) {                                             \
-           if (pos >= size) {                                          \
-              size = 2*size + 1;                                       \
-              rstring = driver_realloc_binary(rstring, size);          \
-           }                                                           \
-           rstring->orig_bytes[pos] = (char) ruc;                      \
-           pos++;                                                      \
-        } else if (ruc <= 0x7FF) {                                     \
-           if (pos + 1 >= size) {                                      \
-              size = 2*size + 2;                                       \
-              rstring = driver_realloc_binary(rstring, size);          \
-           }                                                           \
-           rstring->orig_bytes[pos] = (char) ((ruc >> 6) | 0xC0);      \
-           rstring->orig_bytes[pos+1] = (char) ((ruc | 0x80) & 0xBF);  \
-           pos += 2;                                                   \
-        } else if (ruc <= 0xFFFF) {                                    \
-           if (pos + 2 >= size) {                                      \
-              size = 2*size + 3;                                       \
-              rstring = driver_realloc_binary(rstring, size);          \
-           }                                                           \
-           rstring->orig_bytes[pos] = (char) ((ruc >> 12) | 0xE0);     \
-           rstring->orig_bytes[pos+1] = (char) (((ruc >> 6) | 0x80) & 0xBF); \
-           rstring->orig_bytes[pos+2] = (char) ((ruc | 0x80) & 0xBF);  \
-           pos += 3;                                                   \
-        } else if (ruc <= 0x1FFFFF) {                                  \
-           if (pos + 3 >= size) {                                      \
-              size = 2*size + 4;                                       \
-              rstring = driver_realloc_binary(rstring, size);          \
-           }                                                           \
-           rstring->orig_bytes[pos] = (char) ((ruc >> 18) | 0xF0);     \
-           rstring->orig_bytes[pos+1] = (char) (((ruc >> 12) | 0x80) & 0xBF); \
-           rstring->orig_bytes[pos+2] = (char) (((ruc >> 6) | 0x80) & 0xBF); \
-           rstring->orig_bytes[pos+3] = (char) ((ruc | 0x80) & 0xBF);  \
-           pos += 4;                                                   \
-        }
-
-#define ADD_UCHAR32(str, pos, len, ch)                         \
-           if (pos >= len) {                                   \
-              len = 2*len + 1;                                 \
-              str = driver_realloc(str, len * sizeof(int));    \
-           }                                                   \
-           str[pos] = ch;                                      \
-           pos++;
-
-
-#define ADD_DECOMP(ruc)                                                \
-              info = GetUniCharDecompInfo(ruc);                \
-              if (info >= 0) {                                 \
-                 decomp_len = GetDecompLen(info);              \
-                 decomp_shift = GetDecompShift(info);          \
-                 for (j = 0; j < decomp_len; j++) {            \
-                    ADD_UCHAR32(str32, str32pos, str32len,     \
-                                decompList[decomp_shift + j]); \
-                 }                                             \
-              } else {                                         \
-                 ADD_UCHAR32(str32, str32pos, str32len, ruc);  \
-              }
-
-
-
-static ErlDrvSSizeT stringprep_erl_control(ErlDrvData drv_data,
-                                 unsigned int command,
-                                 char *buf, ErlDrvSizeT len,
-                                 char **rbuf, ErlDrvSizeT rlen)
-{
-   int i, j, pos=1;
-   unsigned char c;
-   int bad = 0;
-   int uc = 0, ruc;
-   int size;
-   int info;
-   int prohibit = 0, tolower = 0;
-   ErlDrvBinary *rstring;
-   int *mc;
-   int *str32;
-   int str32len, str32pos = 0;
-   int decomp_len, decomp_shift;
-   int comp_pos, comp_starter_pos;
-   int cclass_prev, cclass2;
-   int ch1, ch2;
-   int first_ral, last_ral, have_ral, have_l;
-
-   size = len + 1;
-
-   rstring = driver_alloc_binary(size);
-   rstring->orig_bytes[0] = 0;
-
-   str32len = len + 1;
-
-   str32 = driver_alloc(str32len * sizeof(int));
-
-   switch (command)
-   {
-      case 0:
-        prohibit = ACMask;
-        tolower = 1;
-        break;
-
-      case NAMEPREP_COMMAND:
-        prohibit = ACMask;
-        tolower = 1;
-        break;
-
-      case NODEPREP_COMMAND:
-        prohibit = ACMask | C11Mask | C21Mask | XNPMask;
-        tolower = 1;
-        break;
-
-      case RESOURCEPREP_COMMAND:
-        prohibit = ACMask | C21Mask;
-        tolower = 0;
-        break;
-   }
-
-   for (i = 0; i < len; i++)
-   {
-      c = buf[i];
-      if (c < 0x80) {
-        uc = c;
-      } else if (c < 0xC0) {
-        bad = 1;
-      } else if (c < 0xE0) {
-        if (i+1 < len && (buf[i+1] & 0xC0) == 0x80) {
-           uc = ((c & 0x1F) << 6) | (buf[i+1] & 0x3F);
-           i++;
-        } else {
-           bad = 1;
-        }
-      } else if (c < 0xF0) {
-        if (i+2 < len && (buf[i+1] & 0xC0) == 0x80 &&
-            (buf[i+2] & 0xC0) == 0x80) {
-           uc = ((c & 0x0F) << 12)
-              | ((buf[i+1] & 0x3F) << 6)
-              | (buf[i+2] & 0x3F);
-           i += 2;
-        } else {
-           bad = 1;
-        }
-      } else if (c < 0xF8) {
-        if (i+3 < len &&
-            (buf[i+1] & 0xC0) == 0x80 &&
-            (buf[i+2] & 0xC0) == 0x80 &&
-            (buf[i+3] & 0xC0) == 0x80) {
-           uc = ((c & 0x07) << 18)
-              | ((buf[i+1] & 0x3F) << 12)
-              | ((buf[i+2] & 0x3F) << 6)
-              | (buf[i+3] & 0x3F);
-           i += 3;
-           if (uc > 0x10FFFF)
-              bad = 1;
-        } else {
-           bad = 1;
-        }
-      } else {
-        bad = 1;
-      }
-
-      if (bad) {
-        *rbuf = (char *)rstring;
-        driver_free(str32);
-        return 1;
-      }
-      
-      info = GetUniCharInfo(uc);
-
-      if (!(info & B1Mask)) 
-      {
-        if (tolower) {
-           if (!(info & MCMask)) 
-           {
-              ruc = uc + GetDelta(info);
-              ADD_DECOMP(ruc);
-           } else {
-              mc = GetMC(info);
-              for (j = 1; j <= mc[0]; j++) {
-                 ruc = mc[j];
-                 ADD_DECOMP(ruc);
-              }
-           }
-        } else {
-           ruc = uc;
-           ADD_DECOMP(ruc);
-        }
-      }
-   }
-
-   if (str32pos == 0) {
-      rstring->orig_bytes[0] = 1;
-      *rbuf = (char *)rstring;
-      driver_free(str32);
-      return 1;
-   }
-
-   canonical_ordering(str32, str32pos);
-
-   comp_pos = 1;
-   comp_starter_pos = 0;
-   ch1 = str32[0];
-   cclass_prev = GetUniCharCClass(ch1);
-   for (i = 1; i < str32pos; i++)
-   {
-      ch2 = str32[i];
-      cclass2 = GetUniCharCClass(ch2);
-      if ((cclass_prev == 0 || cclass2 > cclass_prev) &&
-         (ruc = compose(ch1, ch2))) {
-        ch1 = ruc;
-      } else {
-        if (cclass2 == 0) {
-           str32[comp_starter_pos] = ch1;
-           comp_starter_pos = comp_pos++;
-           ch1 = ch2;
-           cclass_prev = 0;
-        } else {
-           str32[comp_pos++] = ch2;
-           cclass_prev = cclass2;
-        }
-      }
-   }
-   str32[comp_starter_pos] = ch1;
-   str32pos = comp_pos;
-   
-   last_ral = have_ral = have_l = 0;
-   info = GetUniCharInfo(str32[0]);
-   first_ral = info & D1Mask;
-   for (i = 0; i < str32pos; i++)
-   {
-      ruc = str32[i];
-      info = GetUniCharInfo(ruc);
-      if (info & prohibit) {
-        *rbuf = (char *)rstring;
-        driver_free(str32);
-        return 1;
-      }
-      last_ral = info & D1Mask;
-      have_ral = have_ral || last_ral;
-      have_l |= info & D2Mask;
-      ADD_UCHAR(ruc);
-   }
-
-   if (have_ral && (!first_ral || !last_ral || have_l)) {
-      *rbuf = (char *)rstring;
-      driver_free(str32);
-      return 1;
-   }
-
-   rstring->orig_bytes[0] = 1;
-   *rbuf = (char *)rstring;
-   driver_free(str32);
-   
-   return pos;
-}
-
-
-
-ErlDrvEntry stringprep_driver_entry = {
-   NULL,                       /* F_PTR init, N/A */
-   stringprep_erl_start,       /* L_PTR start, called when port is opened */
-   stringprep_erl_stop,                /* F_PTR stop, called when port is closed */
-   NULL,                       /* F_PTR output, called when erlang has sent */
-   NULL,                       /* F_PTR ready_input, called when input descriptor ready */
-   NULL,                       /* F_PTR ready_output, called when output descriptor ready */
-   "stringprep_drv",           /* char *driver_name, the argument to open_port */
-   NULL,                       /* F_PTR finish, called when unloaded */
-   NULL,                       /* handle */
-   stringprep_erl_control,     /* F_PTR control, port_command callback */
-   NULL,                       /* F_PTR timeout, reserved */
-   NULL,                       /* F_PTR outputv, reserved */
-  /* Added in Erlang/OTP R15B: */
-  NULL,                 /* ready_async */
-  NULL,                 /* flush */
-  NULL,                 /* call */
-  NULL,                 /* event */
-  ERL_DRV_EXTENDED_MARKER,        /* extended_marker */
-  ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */
-  ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */
-  0,                    /* driver_flags */
-  NULL,                 /* handle2 */
-  NULL,                 /* process_exit */
-  NULL                  /* stop_select */
-};
-
-DRIVER_INIT(stringprep_erl) /* must match name in driver_entry */
-{
-    return &stringprep_driver_entry;
-}
-
diff --git a/src/stringprep/stringprep_sup.erl b/src/stringprep/stringprep_sup.erl
deleted file mode 100644 (file)
index 828f854..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : stringprep_sup.erl
-%%% Author  : Mickael Remond <mremond@process-one.net>
-%%% Description : Supervisor for the Stringprep worker.
-%%% Created : 29 Jun 2007 by Mickael Remond <mremond@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%-------------------------------------------------------------------
-
--module(stringprep_sup).
-
--behaviour(supervisor).
-
-%% API
--export([start_link/0]).
-
-%% Supervisor callbacks
--export([init/1]).
-
--define(SERVER, ?MODULE).
-
-%%====================================================================
-%% API functions
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-%% Description: Starts the supervisor
-%%--------------------------------------------------------------------
-start_link() ->
-    supervisor:start_link({local, ?SERVER}, ?MODULE, []).
-
-%%====================================================================
-%% Supervisor callbacks
-%%====================================================================
-%%--------------------------------------------------------------------
-%% Func: init(Args) -> {ok,  {SupFlags,  [ChildSpec]}} |
-%%                     ignore                          |
-%%                     {error, Reason}
-%% Description: Whenever a supervisor is started using 
-%% supervisor:start_link/[2,3], this function is called by the new process 
-%% to find out about restart strategy, maximum restart frequency and child 
-%% specifications.
-%%--------------------------------------------------------------------
-init([]) ->
-    StringPrep = {stringprep, {stringprep, start_link, []},
-                 permanent, brutal_kill, worker, [stringprep]},
-    {ok, {{one_for_all, 10, 1}, [StringPrep]}}.
diff --git a/src/stringprep/uni_data.c b/src/stringprep/uni_data.c
deleted file mode 100644 (file)
index 1c76ee8..0000000
+++ /dev/null
@@ -1,1257 +0,0 @@
-/*
- * uni_data.c --
- *
- *     Declarations of Unicode character information tables.  This file is
- *     automatically generated by the uni_parse.tcl script.  Do not
- *     modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) $Id$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables.  The lower OFFSET_BITS comprise an offset
- * into a page of characters.  The upper bits comprise the page number.
- */
-
-#define OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char pageMap[] = {
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
-    20, 21, 22, 23, 24, 8, 8, 8, 8, 8, 25, 26, 27, 28, 29, 30, 31, 29, 
-    32, 33, 29, 29, 29, 8, 8, 8, 34, 35, 36, 37, 38, 39, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 40, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 41, 21, 21, 21, 21, 42, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 21, 45, 46, 47, 48, 49, 50, 8, 8, 8, 51, 52, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 53, 54, 8, 8, 55, 
-    56, 57, 58, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 59, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 21, 21, 60, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 
-    44, 44, 44, 44, 44, 61
-};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static unsigned short int groupMap[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 
-    2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 
-    2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 
-    2, 2, 5, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 9, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 
-    5, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 11, 5, 10, 5, 10, 5, 10, 5, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 12, 10, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 13, 10, 5, 10, 5, 10, 5, 14, 5, 15, 10, 5, 10, 5, 
-    16, 10, 5, 17, 17, 10, 5, 5, 18, 19, 20, 10, 5, 17, 21, 5, 22, 23, 
-    10, 5, 5, 5, 22, 24, 5, 25, 10, 5, 10, 5, 10, 5, 26, 10, 5, 26, 5, 
-    5, 10, 5, 26, 10, 5, 27, 27, 10, 5, 10, 5, 28, 10, 5, 5, 5, 10, 5, 
-    5, 5, 5, 5, 5, 5, 29, 10, 5, 29, 10, 5, 29, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 30, 29, 10, 5, 10, 5, 31, 32, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 33, 
-    6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 
-    5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 34, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 2, 
-    6, 6, 6, 6, 35, 6, 6, 6, 2, 6, 6, 6, 6, 6, 2, 2, 36, 2, 37, 37, 37, 
-    6, 38, 6, 39, 39, 40, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 41, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 6, 42, 43, 44, 45, 46, 47, 48, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 49, 50, 
-    51, 5, 52, 53, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 54, 54, 54, 54, 54, 54, 
-    54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 2, 2, 2, 
-    2, 6, 2, 2, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 6, 10, 5, 6, 6, 6, 
-    6, 6, 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, 5, 5, 5, 5, 5, 5, 
-    5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 56, 6, 5, 2, 6, 
-    6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 2, 2, 2, 57, 2, 57, 2, 2, 57, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 57, 57, 57, 
-    57, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 6, 6, 6, 
-    57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 58, 2, 2, 2, 2, 2, 2, 2, 57, 57, 2, 
-    2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 57, 57, 57, 
-    57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 
-    57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 5, 6, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 6, 6, 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 2, 
-    6, 6, 5, 2, 2, 2, 2, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 2, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 
-    5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 6, 6, 5, 5, 5, 5, 6, 6, 2, 6, 5, 5, 5, 
-    2, 2, 2, 2, 6, 6, 5, 5, 6, 6, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 
-    6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 2, 2, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 2, 6, 6, 5, 
-    5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 
-    6, 5, 5, 6, 5, 5, 6, 6, 2, 6, 5, 5, 5, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 
-    2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 5, 6, 6, 6, 
-    6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 
-    5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 6, 6, 2, 5, 
-    5, 5, 5, 2, 2, 2, 2, 2, 6, 2, 2, 5, 6, 5, 5, 2, 6, 6, 5, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 
-    5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 
-    6, 5, 5, 6, 6, 5, 5, 5, 5, 6, 6, 2, 5, 5, 2, 5, 2, 2, 2, 6, 6, 6, 5, 
-    5, 6, 6, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 6, 6, 6, 6, 5, 5, 6, 
-    5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 6, 5, 5, 5, 5, 5, 5, 6, 6, 
-    6, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 6, 5, 5, 6, 5, 6, 5, 5, 6, 6, 6, 5, 
-    5, 6, 6, 6, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 
-    6, 6, 6, 5, 5, 2, 5, 5, 6, 6, 6, 5, 5, 5, 6, 5, 5, 5, 2, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 6, 6, 6, 6, 2, 2, 2, 5, 5, 5, 5, 
-    6, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 2, 2, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 5, 5, 
-    5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 
-    5, 5, 6, 6, 6, 6, 5, 2, 5, 5, 5, 5, 5, 6, 2, 5, 5, 6, 5, 5, 2, 2, 6, 
-    6, 6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 6, 6, 6, 6, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 2, 
-    2, 2, 6, 6, 5, 5, 5, 6, 5, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 
-    6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 2, 6, 
-    6, 6, 6, 5, 5, 5, 2, 2, 2, 6, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 
-    2, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 
-    5, 6, 6, 5, 5, 6, 5, 6, 6, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 5, 5, 
-    5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 6, 5, 6, 6, 5, 5, 6, 5, 5, 5, 5, 2, 
-    5, 5, 2, 2, 2, 2, 2, 2, 6, 2, 2, 5, 6, 6, 5, 5, 5, 5, 5, 6, 5, 6, 2, 
-    2, 2, 2, 2, 2, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 5, 2, 2, 2, 
-    2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 
-    2, 2, 2, 2, 5, 2, 2, 5, 5, 5, 5, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 
-    2, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    6, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 2, 2, 2, 2, 5, 2, 6, 6, 6, 2, 2, 5, 
-    2, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 
-    5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 
-    5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 
-    6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 
-    5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 
-    5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 
-    5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 
-    6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 2, 2, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    6, 5, 5, 5, 5, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 5, 5, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 6, 5, 5, 5, 6, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 
-    5, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 2, 
-    5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2, 
-    2, 7, 7, 7, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 
-    6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 5, 10, 5, 10, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 59, 60, 61, 62, 63, 64, 6, 6, 6, 6, 10, 5, 10, 5, 
-    10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 
-    5, 10, 5, 10, 5, 10, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 65, 
-    65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 6, 6, 65, 65, 65, 65, 
-    65, 65, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65, 
-    5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5, 
-    5, 5, 6, 6, 65, 65, 65, 65, 65, 65, 6, 6, 66, 5, 67, 5, 68, 5, 69, 
-    5, 6, 65, 6, 65, 6, 65, 6, 65, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 
-    65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 
-    70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 
-    87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 
-    103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 
-    117, 5, 5, 118, 119, 120, 6, 121, 122, 65, 65, 123, 123, 124, 2, 125, 
-    2, 2, 2, 126, 127, 128, 6, 129, 130, 131, 131, 131, 131, 132, 2, 2, 
-    2, 5, 5, 133, 134, 6, 6, 135, 136, 65, 65, 137, 137, 6, 2, 2, 2, 5, 
-    5, 138, 139, 140, 5, 141, 142, 65, 65, 143, 143, 144, 2, 2, 2, 6, 6, 
-    145, 146, 147, 6, 148, 149, 150, 150, 151, 151, 152, 2, 2, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 153, 153, 153, 154, 58, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 
-    6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 6, 6, 6, 
-    6, 6, 6, 6, 6, 153, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 
-    5, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 2, 2, 2, 2, 2, 2, 2, 2, 155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 2, 2, 156, 157, 2, 2, 2, 158, 2, 159, 5, 160, 161, 
-    162, 5, 5, 163, 164, 165, 5, 2, 163, 166, 2, 2, 167, 167, 167, 168, 
-    169, 2, 2, 170, 171, 172, 2, 168, 2, 173, 2, 174, 2, 175, 176, 177, 
-    177, 2, 5, 178, 178, 2, 179, 5, 5, 5, 5, 5, 5, 2, 6, 6, 5, 180, 181, 
-    2, 2, 2, 2, 2, 182, 5, 5, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 183, 183, 183, 183, 183, 183, 183, 183, 
-    183, 183, 183, 183, 183, 183, 183, 183, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 
-    184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 
-    2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 2, 2, 2, 6, 6, 6, 2, 6, 
-    2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 5, 5, 5, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 2, 2, 
-    5, 5, 5, 5, 5, 2, 2, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 6, 6, 2, 2, 2, 2, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 185, 5, 
-    186, 5, 187, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 188, 189, 190, 191, 192, 
-    193, 194, 195, 5, 5, 196, 197, 198, 5, 5, 5, 199, 200, 201, 202, 203, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 204, 205, 
-    206, 207, 5, 5, 5, 5, 5, 5, 5, 208, 209, 210, 211, 212, 213, 214, 215, 
-    216, 217, 218, 219, 220, 221, 5, 222, 5, 5, 5, 223, 224, 225, 5, 226, 
-    5, 227, 228, 5, 5, 5, 5, 5, 5, 5, 5, 229, 5, 230, 231, 5, 232, 233, 
-    6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 234, 235, 236, 237, 238, 239, 240, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 241, 242, 243, 244, 245, 6, 6, 6, 
-    6, 6, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 57, 57, 57, 57, 57, 6, 57, 
-    6, 57, 57, 6, 57, 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6, 57, 57, 57, 57, 
-    57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 
-    57, 6, 6, 153, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 
-    2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 
-    5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 6, 6, 6, 2, 
-    2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 246, 246, 246, 246, 246, 246, 246, 
-    246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 
-    246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 
-    246, 246, 246, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 
-    6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 247, 
-    247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 
-    247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 248, 
-    248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 
-    248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 5, 5, 5, 5, 
-    5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 249, 
-    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 
-    249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 250, 
-    6, 250, 250, 6, 6, 250, 6, 6, 250, 250, 6, 6, 250, 250, 250, 250, 6, 
-    250, 250, 250, 250, 250, 250, 250, 250, 5, 5, 5, 5, 6, 5, 6, 5, 5, 
-    5, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 251, 251, 251, 251, 
-    251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 
-    251, 251, 251, 251, 251, 251, 251, 251, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 252, 252, 6, 252, 
-    252, 252, 252, 6, 6, 252, 252, 252, 252, 252, 252, 252, 252, 6, 252, 
-    252, 252, 252, 252, 252, 252, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 253, 253, 6, 253, 253, 253, 
-    253, 6, 253, 253, 253, 253, 253, 6, 253, 6, 6, 6, 253, 253, 253, 253, 
-    253, 253, 253, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 254, 254, 254, 254, 254, 254, 254, 254, 
-    254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 
-    254, 254, 254, 254, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 255, 255, 255, 255, 255, 255, 255, 255, 
-    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
-    255, 255, 255, 255, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 256, 256, 256, 256, 256, 256, 256, 256, 
-    256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 
-    256, 256, 256, 256, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 257, 257, 257, 257, 257, 257, 257, 257, 
-    257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 
-    257, 257, 257, 257, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 258, 258, 258, 258, 258, 258, 258, 258, 
-    258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 
-    258, 258, 258, 258, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 259, 259, 259, 259, 259, 259, 259, 259, 
-    259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 
-    259, 259, 259, 259, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 260, 260, 260, 260, 260, 
-    260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 260, 
-    260, 260, 260, 260, 260, 260, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 262, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 263, 
-    263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 
-    263, 263, 264, 263, 263, 263, 263, 263, 263, 263, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 265, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 
-    266, 266, 266, 266, 266, 266, 267, 266, 266, 266, 266, 266, 266, 266, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 268, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 269, 269, 269, 269, 269, 269, 269, 
-    269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269, 
-    269, 269, 269, 269, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 271, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 272, 272, 272, 
-    272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 
-    273, 272, 272, 272, 272, 272, 272, 272, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 274, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
-    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 
-    154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 6, 6
-};
-
-/*
- * Each group represents a unique set of character attributes.  The attributes
- * are encoded into a 32-bit value as follows:
- *
- * Bit  0      A.1 | C.1.2 | C.2.2 | C.3 -- C.9
- *
- * Bit  1      C.1.1
- *
- * Bit  2      C.2.1
- *
- * Bit  3      B.1
- *
- * Bit  4      D.1
- *
- * Bit  5      D.2
- *
- * Bit  6      XNP
- *
- * Bit  7      Case maps to several characters
- *
- * Bits 8-10   Reserved for future use.
- *
- * Bits 11-31  Case delta: delta for case conversions.  This should be the
- *                         highest field so we can easily sign extend.
- */
-
-static int groups[] = {
-    4, 2, 0, 64, 65568, 32, 1, 8, 1587232, 160, 2080, 2208, 4256, 
-    -247776, -548832, 430112, 421920, 419872, 161824, 413728, 415776, 
-    423968, 432160, 428064, 436256, 438304, 446496, 444448, 448544, 
-    4128, 6304, -198624, -114656, -266208, 237568, 8352, 77856, 75808, 
-    131104, 129056, 10400, 12448, -61408, -51168, -26592, -12256, 
-    -18400, -30688, -45024, -110560, -98272, -96224, -122848, -131040, 
-    163872, 98336, 14496, 16, 17, 16544, 18592, 20640, 22688, 24736, 
-    -118752, -16352, 26784, 28832, 30880, 32928, 34976, 37024, 39072, 
-    41120, 43168, 45216, 47264, 49312, 51360, 53408, 55456, 57504, 
-    59552, 61600, 63648, 65696, 67744, 69792, 71840, 73888, 75936, 
-    77984, 80032, 82080, 84128, 86176, 88224, 90272, 92320, 94368, 
-    96416, 98464, 100512, 102560, 104608, 106656, 108704, 110752, 
-    112800, 114848, 116896, 118944, 120992, 123040, 125088, 127136, 
-    129184, 131232, 133280, 135328, 137376, 139424, 141472, -151520, 
-    143520, -14690272, 145568, 147616, 149664, 151712, 153760, -176096, 
-    155808, 157856, 159904, 161952, 164000, -204768, 166048, 168096, 
-    170144, 172192, 174240, -229344, -14304, 176288, 178336, 180384, 
-    182432, 184480, -262112, -258016, 186528, 9, 33, 188544, -17102816, 
-    190592, -16080864, 192640, -17111008, -17113056, -17115104, -17119200, 
-    -17121248, -17117152, 194688, -17123296, -17125344, -17127392, 
-    196736, 198784, 200832, -15394784, -17133536, -17168352, -16920544, 
-    -17190880, -17192928, -17182688, -15488992, -15464416, -17237984, 
-    32800, 53280, 202912, 204960, 207008, 209056, 211104, 213152, 
-    215200, 217248, 219296, 221344, 223392, 225440, 227488, 229536, 
-    231584, 233632, 235680, 237728, 239776, 241824, 243872, 245920, 
-    247968, 250016, 252064, 254112, 256160, 258208, 260256, 262304, 
-    264352, 266400, 268448, 270496, 272544, 274592, 276640, 278688, 
-    280736, 282784, 284832, 286880, 288928, 290976, 293024, 295072, 
-    297120, 299168, 301216, 303264, 305312, 307360, 309408, 311456, 
-    313504, 315552, 317600, 319648, 321696, 323744, 325792, 81952, 
-    -245168096, -245274592, -245381088, -245487584, -245594080, -245700576, 
-    -245807072, -245913568, -246020064, -246126560, -246233056, -246339552, 
-    -246446048, -244824032, -244844512, -244875232, -244942816, -244963296, 
-    -244994016, -245061600, -245082080, -245112800, -245180384, -245200864, 
-    -245231584, -245299168, -245319648, -245350368
-};
-
-/*
- * Table for characters that lowercased to multiple ones
- */
-
-static int multiCaseTable[][4] = {
-    {2, 115, 115}, 
-    {2, 105, 775}, 
-    {2, 700, 110}, 
-    {2, 106, 780}, 
-    {2, 32, 953}, 
-    {3, 953, 776, 769}, 
-    {3, 965, 776, 769}, 
-    {2, 1381, 1410}, 
-    {2, 104, 817}, 
-    {2, 116, 776}, 
-    {2, 119, 778}, 
-    {2, 121, 778}, 
-    {2, 97, 702}, 
-    {2, 965, 787}, 
-    {3, 965, 787, 768}, 
-    {3, 965, 787, 769}, 
-    {3, 965, 787, 834}, 
-    {2, 7936, 953}, 
-    {2, 7937, 953}, 
-    {2, 7938, 953}, 
-    {2, 7939, 953}, 
-    {2, 7940, 953}, 
-    {2, 7941, 953}, 
-    {2, 7942, 953}, 
-    {2, 7943, 953}, 
-    {2, 7936, 953}, 
-    {2, 7937, 953}, 
-    {2, 7938, 953}, 
-    {2, 7939, 953}, 
-    {2, 7940, 953}, 
-    {2, 7941, 953}, 
-    {2, 7942, 953}, 
-    {2, 7943, 953}, 
-    {2, 7968, 953}, 
-    {2, 7969, 953}, 
-    {2, 7970, 953}, 
-    {2, 7971, 953}, 
-    {2, 7972, 953}, 
-    {2, 7973, 953}, 
-    {2, 7974, 953}, 
-    {2, 7975, 953}, 
-    {2, 7968, 953}, 
-    {2, 7969, 953}, 
-    {2, 7970, 953}, 
-    {2, 7971, 953}, 
-    {2, 7972, 953}, 
-    {2, 7973, 953}, 
-    {2, 7974, 953}, 
-    {2, 7975, 953}, 
-    {2, 8032, 953}, 
-    {2, 8033, 953}, 
-    {2, 8034, 953}, 
-    {2, 8035, 953}, 
-    {2, 8036, 953}, 
-    {2, 8037, 953}, 
-    {2, 8038, 953}, 
-    {2, 8039, 953}, 
-    {2, 8032, 953}, 
-    {2, 8033, 953}, 
-    {2, 8034, 953}, 
-    {2, 8035, 953}, 
-    {2, 8036, 953}, 
-    {2, 8037, 953}, 
-    {2, 8038, 953}, 
-    {2, 8039, 953}, 
-    {2, 8048, 953}, 
-    {2, 945, 953}, 
-    {2, 940, 953}, 
-    {2, 945, 834}, 
-    {3, 945, 834, 953}, 
-    {2, 945, 953}, 
-    {2, 8052, 953}, 
-    {2, 951, 953}, 
-    {2, 942, 953}, 
-    {2, 951, 834}, 
-    {3, 951, 834, 953}, 
-    {2, 951, 953}, 
-    {3, 953, 776, 768}, 
-    {3, 953, 776, 769}, 
-    {2, 953, 834}, 
-    {3, 953, 776, 834}, 
-    {3, 965, 776, 768}, 
-    {3, 965, 776, 769}, 
-    {2, 961, 787}, 
-    {2, 965, 834}, 
-    {3, 965, 776, 834}, 
-    {2, 8060, 953}, 
-    {2, 969, 953}, 
-    {2, 974, 953}, 
-    {2, 969, 834}, 
-    {3, 969, 834, 953}, 
-    {2, 969, 953}, 
-    {2, 114, 115}, 
-    {2, 176, 99}, 
-    {2, 176, 102}, 
-    {2, 110, 111}, 
-    {2, 115, 109}, 
-    {3, 116, 101, 108}, 
-    {2, 116, 109}, 
-    {3, 104, 112, 97}, 
-    {2, 97, 117}, 
-    {2, 111, 118}, 
-    {2, 112, 97}, 
-    {2, 110, 97}, 
-    {2, 956, 97}, 
-    {2, 109, 97}, 
-    {2, 107, 97}, 
-    {2, 107, 98}, 
-    {2, 109, 98}, 
-    {2, 103, 98}, 
-    {2, 112, 102}, 
-    {2, 110, 102}, 
-    {2, 956, 102}, 
-    {2, 104, 122}, 
-    {3, 107, 104, 122}, 
-    {3, 109, 104, 122}, 
-    {3, 103, 104, 122}, 
-    {3, 116, 104, 122}, 
-    {2, 112, 97}, 
-    {3, 107, 112, 97}, 
-    {3, 109, 112, 97}, 
-    {3, 103, 112, 97}, 
-    {2, 112, 118}, 
-    {2, 110, 118}, 
-    {2, 956, 118}, 
-    {2, 109, 118}, 
-    {2, 107, 118}, 
-    {2, 109, 118}, 
-    {2, 112, 119}, 
-    {2, 110, 119}, 
-    {2, 956, 119}, 
-    {2, 109, 119}, 
-    {2, 107, 119}, 
-    {2, 109, 119}, 
-    {2, 107, 969}, 
-    {2, 109, 969}, 
-    {2, 98, 113}, 
-    {3, 99, 111, 46}, 
-    {2, 100, 98}, 
-    {2, 103, 121}, 
-    {2, 104, 112}, 
-    {2, 107, 107}, 
-    {2, 107, 109}, 
-    {2, 112, 104}, 
-    {3, 112, 112, 109}, 
-    {2, 112, 114}, 
-    {2, 115, 118}, 
-    {2, 119, 98}, 
-    {2, 102, 102}, 
-    {2, 102, 105}, 
-    {2, 102, 108}, 
-    {3, 102, 102, 105}, 
-    {3, 102, 102, 108}, 
-    {2, 115, 116}, 
-    {2, 115, 116}, 
-    {2, 1396, 1398}, 
-    {2, 1396, 1381}, 
-    {2, 1396, 1387}, 
-    {2, 1406, 1398}, 
-    {2, 1396, 1389}
-};
-
-/*
- * The following constants are used to determine the category of a
- * Unicode character.
- */
-
-#define ACMask  (1 << 0)
-#define C11Mask (1 << 1)
-#define C21Mask (1 << 2)
-#define B1Mask  (1 << 3)
-#define D1Mask  (1 << 4)
-#define D2Mask  (1 << 5)
-#define XNPMask (1 << 6)
-#define MCMask  (1 << 7)
-
-/*
- * The following macros extract the fields of the character info.  The
- * GetDelta() macro is complicated because we can't rely on the C compiler
- * to do sign extension on right shifts.
- */
-
-#define GetCaseType(info) (((info) & 0xE0) >> 5)
-#define GetCategory(info) ((info) & 0x1F)
-#define GetDelta(info) (((info) > 0) ? ((info) >> 11) : (~(~((info)) >> 11)))
-#define GetMC(info) (multiCaseTable[GetDelta(info)])
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharInfo(ch) (groups[groupMap[(pageMap[(((int)(ch)) & 0x1fffff) >> OFFSET_BITS] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))]])
-
diff --git a/src/stringprep/uni_norm.c b/src/stringprep/uni_norm.c
deleted file mode 100644 (file)
index 7575f14..0000000
+++ /dev/null
@@ -1,3264 +0,0 @@
-/*
- * uni_norm.c --
- *
- *     Declarations of Unicode character information tables.  This file is
- *     automatically generated by the uni_parse2.tcl script.  Do not
- *     modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) $Id$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables.  The lower CCLASS_OFFSET_BITS comprise an offset
- * into a page of characters.  The upper bits comprise the page number.
- */
-
-#define CCLASS_OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char cclassPageMap[] = {
-    0, 0, 0, 1, 2, 3, 4, 5, 0, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 
-    0, 0, 14, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * The cclassGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a combining class number.
- */
-
-static unsigned char cclassGroupMap[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 
-    230, 230, 230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 
-    232, 216, 220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 
-    202, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 
-    1, 1, 220, 220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 
-    230, 220, 220, 220, 230, 230, 230, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 234, 233, 230, 230, 230, 230, 230, 
-    230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 230, 230, 230, 230, 220, 230, 230, 
-    230, 222, 220, 230, 230, 230, 230, 230, 230, 0, 220, 220, 220, 220, 
-    220, 230, 230, 220, 230, 230, 222, 228, 230, 10, 11, 12, 13, 14, 15, 
-    16, 17, 18, 19, 0, 20, 21, 22, 0, 23, 0, 24, 25, 0, 230, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 
-    33, 34, 230, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 
-    230, 230, 230, 230, 230, 230, 0, 0, 230, 230, 230, 230, 220, 230, 0, 
-    0, 230, 230, 0, 220, 230, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 220, 230, 230, 220, 
-    220, 220, 230, 220, 220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 
-    220, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230, 
-    230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 122, 122, 122, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 130, 0, 132, 
-    0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, 230, 
-    230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 1, 
-    1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0, 0, 230, 0, 0, 0, 
-    1, 1, 230, 220, 230, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 218, 228, 232, 222, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216, 
-    216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 
-    220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-#define GetUniCharCClass(ch) (cclassGroupMap[(cclassPageMap[(((int)(ch)) & 0x1fffff) >> CCLASS_OFFSET_BITS] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))])
-
-
-#define DECOMP_OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char decompPageMap[] = {
-    0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 16, 17, 18, 19, 20, 21, 22, 7, 7, 7, 7, 
-    7, 23, 7, 7, 7, 24, 25, 26, 27, 28, 29, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 7, 38, 39, 40, 
-    41, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 42, 43, 44, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-};
-
-/*
- * The decompGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a length and
- * shift of decomposition sequence in decompList
- */
-
-static int decompGroupMap[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, -1, -1, -1, -1, 131073, 
-    -1, 65539, -1, -1, -1, -1, 131076, -1, -1, 65542, 65543, 131080, 65546, 
-    -1, -1, 131083, 65549, 65550, -1, 196623, 196626, 196629, -1, 131096, 
-    131098, 131100, 131102, 131104, 131106, -1, 131108, 131110, 131112, 
-    131114, 131116, 131118, 131120, 131122, 131124, -1, 131126, 131128, 
-    131130, 131132, 131134, 131136, -1, -1, 131138, 131140, 131142, 131144, 
-    131146, -1, -1, 131148, 131150, 131152, 131154, 131156, 131158, -1, 
-    131160, 131162, 131164, 131166, 131168, 131170, 131172, 131174, 131176, 
-    -1, 131178, 131180, 131182, 131184, 131186, 131188, -1, -1, 131190, 
-    131192, 131194, 131196, 131198, -1, 131200, 131202, 131204, 131206, 
-    131208, 131210, 131212, 131214, 131216, 131218, 131220, 131222, 131224, 
-    131226, 131228, 131230, 131232, -1, -1, 131234, 131236, 131238, 131240, 
-    131242, 131244, 131246, 131248, 131250, 131252, 131254, 131256, 131258, 
-    131260, 131262, 131264, 131266, 131268, 131270, 131272, -1, -1, 131274, 
-    131276, 131278, 131280, 131282, 131284, 131286, 131288, 131290, -1, 
-    131292, 131294, 131296, 131298, 131300, 131302, -1, 131304, 131306, 
-    131308, 131310, 131312, 131314, 131316, 131318, -1, -1, 131320, 131322, 
-    131324, 131326, 131328, 131330, 131332, -1, -1, 131334, 131336, 131338, 
-    131340, 131342, 131344, -1, -1, 131346, 131348, 131350, 131352, 131354, 
-    131356, 131358, 131360, 131362, 131364, 131366, 131368, 131370, 131372, 
-    131374, 131376, 131378, 131380, -1, -1, 131382, 131384, 131386, 131388, 
-    131390, 131392, 131394, 131396, 131398, 131400, 131402, 131404, 131406, 
-    131408, 131410, 131412, 131414, 131416, 131418, 131420, 131422, 131424, 
-    131426, 65892, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 131429, 131431, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 131433, 131435, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 196973, 196976, 196979, 131446, 131448, 
-    131450, 131452, 131454, 131456, 131458, 131460, 131462, 131464, 131466, 
-    131468, 131470, 131472, 197010, 197013, 197016, 197019, 197022, 197025, 
-    197028, 197031, -1, 197034, 197037, 197040, 197043, 131510, 131512, 
-    -1, -1, 131514, 131516, 131518, 131520, 131522, 131524, 197062, 197065, 
-    131532, 131534, 131536, 131538, 131540, 131542, 131544, 131546, -1, 
-    -1, 131548, 131550, 197088, 197091, 131558, 131560, 131562, 131564, 
-    131566, 131568, 131570, 131572, 131574, 131576, 131578, 131580, 131582, 
-    131584, 131586, 131588, 131590, 131592, 131594, 131596, 131598, 131600, 
-    131602, 131604, 131606, 131608, 131610, 131612, 131614, 131616, 131618, 
-    131620, -1, -1, 131622, 131624, -1, -1, -1, -1, -1, -1, 131626, 131628, 
-    131630, 131632, 197170, 197173, 197176, 197179, 131646, 131648, 197186, 
-    197189, 131656, 131658, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66124, 66125, 66126, 66127, 
-    66128, 66129, 66130, 66131, 66132, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 131669, 131671, 131673, 131675, 131677, 131679, 
-    -1, -1, 66145, 66146, 65892, 66147, 66148, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    66149, 66150, -1, 66151, 131688, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 66154, -1, -1, -1, -1, -1, 131691, -1, -1, -1, 66157, 
-    -1, -1, -1, -1, -1, 131080, 197230, 131697, 66163, 131700, 131702, 
-    131704, -1, 131706, -1, 131708, 131710, 197248, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 131715, 131717, 131719, 131721, 131723, 131725, 197263, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 131730, 131732, 131734, 131736, 131738, 
-    -1, 66204, 66205, 66206, 131708, 131717, 66207, 66208, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 66209, 66210, 66211, -1, 66212, 66213, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 131750, 131752, -1, 131754, -1, -1, 
-    -1, 131756, -1, -1, -1, -1, 131758, 131760, 131762, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 131764, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 131766, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131768, 131770, -1, 
-    131772, -1, -1, -1, 131774, -1, -1, -1, -1, 131776, 131778, 131780, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 131782, 131784, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131786, 
-    131788, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131790, 
-    131792, 131794, 131796, -1, -1, 131798, 131800, -1, -1, 131802, 131804, 
-    131806, 131808, 131810, 131812, -1, -1, 131814, 131816, 131818, 131820, 
-    131822, 131824, -1, -1, 131826, 131828, 131830, 131832, 131834, 131836, 
-    131838, 131840, 131842, 131844, 131846, 131848, -1, -1, 131850, 131852, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 131854, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 131856, 131858, 131860, 131862, 131864, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131866, 131868, 131870, 131872, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 131874, -1, 131876, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 131878, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131880, -1, -1, -1, -1, -1, 
-    -1, -1, 131882, -1, -1, 131884, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 131886, 131888, 131890, 131892, 
-    131894, 131896, 131898, 131900, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131902, 131904, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131906, 
-    131908, -1, 131910, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 131912, -1, -1, 131914, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 131916, 131918, 131920, -1, -1, 
-    131922, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131924, -1, 
-    -1, 131926, 131928, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 131930, 131932, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131934, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131936, 131938, 
-    131940, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 131942, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 131944, -1, -1, -1, -1, -1, -1, 131946, 
-    131948, -1, 131950, 197488, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131955, 131957, 
-    131959, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 131961, -1, 131963, 197501, 131968, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131970, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 131972, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131974, 
-    131976, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66442, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 131979, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131981, -1, -1, 
-    -1, -1, 131983, -1, -1, -1, -1, 131985, -1, -1, -1, -1, 131987, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131989, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 131991, -1, 131993, 131995, 197533, 132000, 197538, 
-    -1, -1, -1, -1, -1, -1, -1, 132005, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 132007, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 132009, -1, -1, -1, -1, 132011, -1, -1, -1, -1, 132013, 
-    -1, -1, -1, -1, 132015, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 132017, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 132019, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 132021, 132023, 132025, 132027, 132029, 
-    132031, 132033, 132035, 197573, 197576, 132043, 132045, 132047, 132049, 
-    132051, 132053, 132055, 132057, 132059, 132061, 197599, 197602, 197605, 
-    197608, 132075, 132077, 132079, 132081, 197619, 197622, 132089, 132091, 
-    132093, 132095, 132097, 132099, 132101, 132103, 132105, 132107, 132109, 
-    132111, 132113, 132115, 132117, 132119, 197657, 197660, 132127, 132129, 
-    132131, 132133, 132135, 132137, 132139, 132141, 197679, 197682, 132149, 
-    132151, 132153, 132155, 132157, 132159, 132161, 132163, 132165, 132167, 
-    132169, 132171, 132173, 132175, 132177, 132179, 132181, 132183, 197721, 
-    197724, 197727, 197730, 197733, 197736, 197739, 197742, 132209, 132211, 
-    132213, 132215, 132217, 132219, 132221, 132223, 197761, 197764, 132231, 
-    132233, 132235, 132237, 132239, 132241, 197779, 197782, 197785, 197788, 
-    197791, 197794, 132261, 132263, 132265, 132267, 132269, 132271, 132273, 
-    132275, 132277, 132279, 132281, 132283, 132285, 132287, 197825, 197828, 
-    197831, 197834, 132301, 132303, 132305, 132307, 132309, 132311, 132313, 
-    132315, 132317, 132319, 132321, 132323, 132325, 132327, 132329, 132331, 
-    132333, 132335, 132337, 132339, 132341, 132343, 132345, 132347, 132349, 
-    132351, 132353, 132355, 132357, 132359, 132361, 132237, -1, -1, -1, 
-    -1, 132363, 132365, 132367, 132369, 197907, 197910, 197913, 197916, 
-    197919, 197922, 197925, 197928, 197931, 197934, 197937, 197940, 197943, 
-    197946, 197949, 197952, 197955, 197958, 197961, 197964, 132431, 132433, 
-    132435, 132437, 132439, 132441, 197979, 197982, 197985, 197988, 197991, 
-    197994, 197997, 198000, 198003, 198006, 132473, 132475, 132477, 132479, 
-    132481, 132483, 132485, 132487, 198025, 198028, 198031, 198034, 198037, 
-    198040, 198043, 198046, 198049, 198052, 198055, 198058, 198061, 198064, 
-    198067, 198070, 198073, 198076, 198079, 198082, 132549, 132551, 132553, 
-    132555, 198093, 198096, 198099, 198102, 198105, 198108, 198111, 198114, 
-    198117, 198120, 132587, 132589, 132591, 132593, 132595, 132597, 132599, 
-    132601, -1, -1, -1, -1, -1, -1, 132603, 132605, 198143, 198146, 198149, 
-    198152, 198155, 198158, 132625, 132627, 198165, 198168, 198171, 198174, 
-    198177, 198180, 132647, 132649, 198187, 198190, 198193, 198196, -1, 
-    -1, 132663, 132665, 198203, 198206, 198209, 198212, -1, -1, 132679, 
-    132681, 198219, 198222, 198225, 198228, 198231, 198234, 132701, 132703, 
-    198241, 198244, 198247, 198250, 198253, 198256, 132723, 132725, 198263, 
-    198266, 198269, 198272, 198275, 198278, 132745, 132747, 198285, 198288, 
-    198291, 198294, 198297, 198300, 132767, 132769, 198307, 198310, 198313, 
-    198316, -1, -1, 132783, 132785, 198323, 198326, 198329, 198332, -1, 
-    -1, 132799, 132801, 198339, 198342, 198345, 198348, 198351, 198354, 
-    -1, 132821, -1, 198359, -1, 198362, -1, 198365, 132832, 132834, 198372, 
-    198375, 198378, 198381, 198384, 198387, 132854, 132856, 198394, 198397, 
-    198400, 198403, 198406, 198409, 132876, 131719, 132878, 131721, 132880, 
-    131723, 132882, 131725, 132884, 131734, 132886, 131736, 132888, 131738, 
-    -1, -1, 198426, 198429, 263968, 263972, 263976, 263980, 263984, 263988, 
-    198456, 198459, 263998, 264002, 264006, 264010, 264014, 264018, 198486, 
-    198489, 264028, 264032, 264036, 264040, 264044, 264048, 198516, 198519, 
-    264058, 264062, 264066, 264070, 264074, 264078, 198546, 198549, 264088, 
-    264092, 264096, 264100, 264104, 264108, 198576, 198579, 264118, 264122, 
-    264126, 264130, 264134, 264138, 133070, 133072, 198610, 133077, 198615, 
-    -1, 133082, 198620, 133087, 133089, 133091, 131697, 133093, 133095, 
-    67561, 133095, 133098, 198636, 198639, 133106, 198644, -1, 133111, 
-    198649, 133116, 131700, 133118, 131702, 133120, 198658, 198661, 198664, 
-    133131, 133133, 198671, 197248, -1, -1, 133138, 198676, 133143, 133145, 
-    133147, 131704, -1, 198685, 198688, 198691, 133158, 133160, 198698, 
-    197263, 133165, 133167, 133169, 198707, 133174, 133176, 133178, 131708, 
-    133180, 198718, 197230, 67649, -1, -1, 198722, 133189, 198727, -1, 
-    133194, 198732, 133199, 131706, 133201, 131710, 133203, 131080, 133205, 
-    -1, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 
-    65536, 65536, -1, -1, -1, -1, -1, -1, 67671, -1, -1, -1, -1, -1, 133208, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67674, 133211, 198749, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, 133216, 198754, 
-    -1, 133221, 198759, -1, -1, -1, -1, 133226, -1, 133228, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 133230, 133232, 133234, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 264308, -1, -1, -1, -1, -1, -1, -1, 65536, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67704, 
-    67705, -1, -1, 67706, 67707, 67708, 67709, 67710, 67711, 67712, 67713, 
-    67714, 67715, 67716, 67717, 67704, 65549, 65542, 65543, 67706, 67707, 
-    67708, 67709, 67710, 67711, 67712, 67713, 67714, 67715, 67716, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 133254, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 198792, 198795, 67726, 
-    133263, -1, 198801, 198804, 67735, -1, 133272, 67738, 67739, 67739, 
-    67739, 66124, 67740, 67741, 67741, 67742, 66146, -1, 67743, 133280, 
-    -1, -1, 67746, 67747, 67748, 67748, 67748, -1, -1, 133285, 198823, 
-    133290, -1, 67756, -1, 67757, -1, 67756, -1, 67758, 131106, 67759, 
-    67726, -1, 67760, 67761, 67762, -1, 67763, 65550, 67764, 67765, 67766, 
-    67767, 67705, -1, -1, -1, 67768, 67769, 67770, 67771, -1, -1, -1, -1, 
-    67772, 67773, 67760, 67705, 66126, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 198846, 198849, 198852, 198855, 198858, 198861, 198864, 198867, 
-    198870, 198873, 198876, 198879, 133346, 67741, 133348, 198886, 133353, 
-    67819, 133356, 198894, 264433, 133365, 67831, 133368, 198906, 67742, 
-    67726, 67772, 67763, 67705, 133373, 198911, 133378, 67844, 133381, 
-    198919, 264458, 133390, 66147, 133392, 198930, 66146, 67861, 67773, 
-    67862, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133399, 133401, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133403, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133405, 133407, 
-    133409, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 133411, -1, -1, -1, -1, 133413, -1, -1, 133415, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 133417, -1, 133419, -1, -1, -1, -1, -1, 133421, 198959, 
-    -1, 133426, 198964, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 133431, -1, -1, 133433, -1, -1, 133435, -1, 133437, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 133439, -1, 133441, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 133443, 133445, 133447, 133449, 133451, -1, -1, 133453, 
-    133455, -1, -1, 133457, 133459, -1, -1, -1, -1, -1, -1, 133461, 133463, 
-    -1, -1, 133465, 133467, -1, -1, 133469, 133471, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133473, 133475, 133477, 
-    133479, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133481, 
-    133483, 133485, 133487, -1, -1, -1, -1, -1, -1, 133489, 133491, 133493, 
-    133495, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67961, 67962, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65549, 
-    65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 133499, 133501, 
-    133503, 133505, 133507, 133509, 133511, 133513, 133515, 133517, 133519, 
-    199057, 199060, 199063, 199066, 199069, 199072, 199075, 199078, 199081, 
-    264620, 264624, 264628, 264632, 264636, 264640, 264644, 264648, 264652, 
-    264656, 264660, 133592, 133594, 133596, 133598, 133600, 133602, 133604, 
-    133606, 133608, 199146, 199149, 199152, 199155, 199158, 199161, 199164, 
-    199167, 199170, 199173, 199176, 199179, 199182, 199185, 199188, 199191, 
-    199194, 199197, 199200, 199203, 199206, 199209, 199212, 199215, 199218, 
-    199221, 199224, 199227, 199230, 199233, 199236, 199239, 199242, 199245, 
-    199248, 199251, 199254, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 
-    67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 
-    67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 
-    68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 
-    66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 
-    67844, 66131, 66147, 66132, 68201, 67704, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 264810, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199278, 133745, 199283, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133750, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 68216, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 68217, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 68218, 68219, 68220, 68221, 68222, 68223, 68224, 68225, 
-    68226, 68227, 68228, 68229, 68230, 68231, 68232, 68233, 68234, 68235, 
-    68236, 68237, 68238, 68239, 68240, 68241, 68242, 68243, 68244, 68245, 
-    68246, 68247, 68248, 68249, 68250, 68251, 68252, 68253, 68254, 68255, 
-    68256, 68257, 68258, 68259, 68260, 68261, 68262, 68263, 68264, 68265, 
-    68266, 68267, 68268, 68269, 68270, 68271, 68272, 68273, 68274, 68275, 
-    68276, 68277, 68278, 68279, 68280, 68281, 68282, 68283, 68284, 68285, 
-    68286, 68287, 68288, 68289, 68290, 68291, 68292, 68293, 68294, 68295, 
-    68296, 68297, 68298, 68299, 68300, 68301, 68302, 68303, 68304, 68305, 
-    68306, 68307, 68308, 68309, 68310, 68311, 68312, 68313, 68314, 68315, 
-    68316, 68317, 68318, 68319, 68320, 68321, 68322, 68323, 68324, 68325, 
-    68326, 68327, 68328, 68329, 68330, 68331, 68332, 68333, 68334, 68335, 
-    68336, 68337, 68338, 68339, 68340, 68341, 68342, 68343, 68344, 68345, 
-    68346, 68347, 68348, 68349, 68350, 68351, 68352, 68353, 68354, 68355, 
-    68356, 68357, 68358, 68359, 68360, 68361, 68362, 68363, 68364, 68365, 
-    68366, 68367, 68368, 68369, 68370, 68371, 68372, 68373, 68374, 68375, 
-    68376, 68377, 68378, 68379, 68380, 68381, 68382, 68383, 68384, 68385, 
-    68386, 68387, 68388, 68389, 68390, 68391, 68392, 68393, 68394, 68395, 
-    68396, 68397, 68398, 68399, 68400, 68401, 68402, 68403, 68404, 68405, 
-    68406, 68407, 68408, 68409, 68410, 68411, 68412, 68413, 68414, 68415, 
-    68416, 68417, 68418, 68419, 68420, 68421, 68422, 68423, 68424, 68425, 
-    68426, 68427, 68428, 68429, 68430, 68431, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 65536, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 68432, -1, 68241, 68433, 68434, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133971, -1, 133973, 
-    -1, 133975, -1, 133977, -1, 133979, -1, 133981, -1, 133983, -1, 133985, 
-    -1, 133987, -1, 133989, -1, 133991, -1, 133993, -1, -1, 133995, -1, 
-    133997, -1, 133999, -1, -1, -1, -1, -1, -1, 134001, 134003, -1, 134005, 
-    134007, -1, 134009, 134011, -1, 134013, 134015, -1, 134017, 134019, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 134021, -1, -1, -1, -1, -1, -1, 134023, 134025, 
-    -1, 134027, 134029, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    134031, -1, 134033, -1, 134035, -1, 134037, -1, 134039, -1, 134041, 
-    -1, 134043, -1, 134045, -1, 134047, -1, 134049, -1, 134051, -1, 134053, 
-    -1, -1, 134055, -1, 134057, -1, 134059, -1, -1, -1, -1, -1, -1, 134061, 
-    134063, -1, 134065, 134067, -1, 134069, 134071, -1, 134073, 134075, 
-    -1, 134077, 134079, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134081, -1, -1, 134083, 134085, 
-    134087, 134089, -1, -1, -1, 134091, 134093, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 68559, 68560, 68561, 68562, 68563, 
-    68564, 68565, 68566, 68567, 68568, 68569, 68570, 68571, 68572, 68573, 
-    68574, 68575, 68576, 68577, 68578, 68579, 68580, 68581, 68582, 68583, 
-    68584, 68585, 68586, 68587, 68588, 68589, 68590, 68591, 68592, 68593, 
-    68594, 68595, 68596, 68597, 68598, 68599, 68600, 68601, 68602, 68603, 
-    68604, 68605, 68606, 68607, 68608, 68609, 68610, 68611, 68612, 68613, 
-    68614, 68615, 68616, 68617, 68618, 68619, 68620, 68621, 68622, 68623, 
-    68624, 68625, 68626, 68627, 68628, 68629, 68630, 68631, 68632, 68633, 
-    68634, 68635, 68636, 68637, 68638, 68639, 68640, 68641, 68642, 68643, 
-    68644, 68645, 68646, 68647, 68648, 68649, 68650, 68651, 68652, -1, 
-    -1, -1, 68218, 68224, 68653, 68654, 68655, 68656, 68657, 68658, 68222, 
-    68659, 68660, 68661, 68662, 68226, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 199735, 199738, 199741, 199744, 199747, 199750, 199753, 
-    199756, 199759, 199762, 199765, 199768, 199771, 199774, 265313, 265317, 
-    265321, 265325, 265329, 265333, 265337, 265341, 265345, 265349, 265353, 
-    265357, 265361, 265365, 265369, -1, -1, -1, 199837, 199840, 199843, 
-    199846, 199849, 199852, 199855, 199858, 199861, 199864, 199867, 199870, 
-    199873, 199876, 199879, 199882, 199885, 199888, 199891, 199894, 199897, 
-    199900, 199903, 199906, 199909, 199912, 199915, 199918, 199921, 199924, 
-    199927, 199930, 199933, 199936, 199939, 199942, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 134409, 134411, 134413, 134415, 134417, 
-    134419, 134421, 134423, 134425, 134427, 134429, 134431, 134433, 134435, 
-    134437, 68559, 68562, 68565, 68567, 68575, 68576, 68579, 68581, 68582, 
-    68584, 68585, 68586, 68587, 68588, 134439, 134441, 134443, 134445, 
-    134447, 134449, 134451, 134453, 134455, 134457, 134459, 134461, 134463, 
-    134465, -1, -1, -1, -1, 68218, 68224, 68653, 68654, 68931, 68932, 68933, 
-    68229, 68934, 68241, 68291, 68303, 68302, 68292, 68384, 68249, 68289, 
-    68935, 68936, 68937, 68938, 68939, 68940, 68941, 68942, 68943, 68944, 
-    68255, 68945, 68946, 68947, 68948, 68949, 68950, 68951, 68952, 68655, 
-    68656, 68657, 68953, 68954, 68955, 68956, 68957, 68958, 68959, 68960, 
-    68961, 68962, 134499, 134501, 134503, 134505, 134507, 134509, 134511, 
-    134513, 134515, 134517, 134519, 134521, 134523, 134525, 134527, 134529, 
-    134531, 134533, 134535, 134537, 134539, 134541, 134543, 134545, 200083, 
-    200086, 200089, -1, -1, -1, -1, 69020, 69021, 69022, 69023, 69024, 
-    69025, 69026, 69027, 69028, 69029, 69030, 69031, 69032, 69033, 69034, 
-    69035, 69036, 69037, 69038, 69039, 69040, 69041, 69042, 69043, 69044, 
-    69045, 69046, 69047, 69048, 69049, 69050, 69051, 69052, 69053, 69054, 
-    69055, 69056, 69057, 69058, 69059, 69060, 69061, 69062, 69063, 69064, 
-    69065, 69066, -1, 331211, 265680, 331220, 200153, 331228, 200161, 200164, 
-    396775, 265709, 200177, 200180, 200183, 265722, 265726, 265730, 265734, 
-    265738, 265742, 265746, 396822, 134684, 396830, 396836, 331306, 265775, 
-    396851, 396857, 265791, 200259, 200262, 265801, 265805, 331345, 331350, 
-    200283, 200286, 265825, 200293, 200296, 134763, 134765, 200303, 200306, 
-    396917, 265851, 331391, 396932, 265866, 200334, 200337, 396948, 265882, 
-    396958, 200356, 331431, 200364, 265903, 200371, 265910, 331450, 265919, 
-    331459, 265928, 134860, 331470, 200403, 200406, 265945, 200413, 200416, 
-    200419, 331494, 265963, 134895, 397041, 200439, 331514, 265983, 265987, 
-    200455, 200458, 265997, 134929, 266003, 331543, 134940, 397086, 200484, 
-    134951, 134953, 134955, 134957, 134959, 134961, 134963, 134965, 134967, 
-    134969, 200507, 200510, 200513, 200516, 200519, 200522, 200525, 200528, 
-    200531, 200534, 200537, 200540, 200543, 200546, 200549, 200552, 135019, 
-    135021, 200559, 135026, 135028, -1, -1, -1, -1, 135030, 135032, 135034, 
-    135036, 266110, 135042, 135044, 135046, 135048, 135050, 135052, 135054, 
-    135056, 200594, 266133, 135065, 135067, 135069, 135071, 135073, 135075, 
-    135077, 200615, 200618, 200621, 200624, 135091, 135093, 135095, 135097, 
-    135099, 135101, 135103, 135105, 135107, 135109, 200647, 200650, 135117, 
-    200655, 200658, 200661, 135128, 200666, 200669, 266208, 135140, 200678, 
-    200681, 200684, 200687, 331762, 397303, 135165, 135167, 135169, 135171, 
-    135173, 135175, 135177, 135179, 135181, 135183, 135185, 135187, 135189, 
-    135191, 135193, 135195, 135197, 135199, 266273, 135205, 135207, 135209, 
-    266283, 200751, 135218, 135220, 135222, 135224, 135226, 135228, 135230, 
-    135232, 135234, 135236, 200774, 135241, 135243, 200781, 200784, 135251, 
-    266325, 200793, 135260, 135262, 135264, 135266, -1, -1, 135268, 135270, 
-    135272, 135274, 135276, 135278, 135280, 135282, 135284, 200822, 200825, 
-    200828, 200831, 200834, 200837, 200840, 200843, 200846, 200849, 200852, 
-    200855, 200858, 200861, 200864, 200867, 200870, 200873, 200876, 200879, 
-    200882, 200885, -1, 69816, 69817, 68376, 69818, 69819, 69820, 69821, 
-    68430, 68430, 69822, 68384, 69823, 69824, 69825, 69826, 69827, 69828, 
-    69829, 69830, 69831, 69832, 69833, 69834, 69835, 69836, 69837, 69838, 
-    69839, 69840, 69841, 69842, 69843, 69844, 69845, 69846, 69847, 69848, 
-    69849, 69850, 69851, 69852, 69853, 69854, 69855, 69856, 69857, 69858, 
-    69859, 69860, 69861, 69862, 69863, 68342, 69864, 69865, 69866, 69867, 
-    69868, 69869, 69870, 69871, 69872, 69873, 69874, 68415, 69875, 69876, 
-    69877, 69878, 69879, 69880, 69881, 69882, 69883, 69884, 69885, 69886, 
-    69887, 69888, 69889, 69890, 69891, 69892, 69893, 69894, 69895, 69896, 
-    69897, 69898, 69899, 69900, 69901, 69832, 69902, 69903, 69904, 69905, 
-    69906, 69907, 69908, 69909, 69910, 69911, 69912, 69913, 69914, 69915, 
-    69916, 69917, 69918, 69919, 69920, 69921, 68378, 69922, 69923, 69924, 
-    69925, 69926, 69927, 69928, 69929, 69930, 69931, 69932, 69933, 69934, 
-    69935, 69936, 68255, 69937, 69938, 69939, 69940, 69941, 69942, 69943, 
-    69944, 68236, 69945, 69946, 69947, 69948, 69949, 69950, 69951, 69952, 
-    69953, 69954, 69955, 69956, 69957, 69958, 69959, 69960, 69961, 69962, 
-    69963, 69964, 69965, 69966, 69920, 69967, 69968, 69969, 69970, 69971, 
-    69972, 69973, 69974, 69904, 69975, 69976, 69977, 69978, 69979, 69980, 
-    69981, 69982, 69983, 69984, 69985, 69986, 69987, 69988, 69989, 69990, 
-    69991, 69992, 69993, 69994, 69832, 69995, 69996, 69997, 69998, 68429, 
-    69999, 70000, 70001, 70002, 70003, 70004, 70005, 70006, 70007, 70008, 
-    70009, 70010, 68932, 70011, 70012, 70013, 70014, 70015, 70016, 70017, 
-    70018, 70019, 69906, 70020, 70021, 70022, 70023, 70024, 70025, 70026, 
-    70027, 70028, 70029, 70030, 70031, 70032, 68383, 70033, 70034, 70035, 
-    70036, 70037, 70038, 70039, 70040, 70041, 70042, 70043, 70044, 70045, 
-    68334, 70046, 70047, 70048, 70049, 70050, 70051, 70052, 70053, 70054, 
-    70055, 70056, 70057, 70058, 70059, 70060, 70061, 68361, 70062, 68364, 
-    70063, 70064, 70065, -1, -1, 70066, -1, 70067, -1, -1, 70068, 70069, 
-    70070, 70071, 70072, 70073, 70074, 70075, 70076, 68341, -1, 70077, 
-    -1, 70078, -1, -1, 70079, 70080, -1, -1, -1, 70081, 70082, 70083, 70084, 
-    -1, -1, 70085, 70086, 70087, 70088, 70089, 70090, 70091, 70092, 70093, 
-    70094, 70095, 70096, 68262, 70097, 70098, 70099, 70100, 70101, 70102, 
-    70103, 70104, 70105, 70106, 70107, 70108, 70109, 70110, 70111, 68937, 
-    70112, 70113, 70114, 70115, 68941, 70116, 70117, 70118, 70119, 70120, 
-    69956, 70121, 70122, 70123, 70124, 70125, 70126, 70126, 70127, 70128, 
-    70129, 70130, 70131, 70132, 70133, 70134, 70079, 70135, 70136, 70137, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 135674, 135676, 
-    135678, 201216, 201219, 135686, 135686, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 135688, 135690, 135692, 135694, 135696, -1, -1, 
-    -1, -1, -1, 135698, -1, 135700, 70166, 67764, 67767, 70167, 70168, 
-    70169, 70170, 70171, 70172, 67712, 135709, 135711, 201249, 201252, 
-    135719, 135721, 135723, 135725, 135727, 135729, 135731, 135733, 135735, 
-    -1, 135737, 135739, 135741, 135743, 135745, -1, 135747, -1, 135749, 
-    135751, -1, 135753, 135755, -1, 135757, 135759, 135761, 135763, 135765, 
-    135767, 135769, 135771, 135773, 135775, 70241, 70241, 70242, 70242, 
-    70242, 70242, 70243, 70243, 70243, 70243, 70244, 70244, 70244, 70244, 
-    70245, 70245, 70245, 70245, 70246, 70246, 70246, 70246, 70247, 70247, 
-    70247, 70247, 70248, 70248, 70248, 70248, 70249, 70249, 70249, 70249, 
-    70250, 70250, 70250, 70250, 70251, 70251, 70251, 70251, 70252, 70252, 
-    70252, 70252, 70253, 70253, 70253, 70253, 70254, 70254, 70255, 70255, 
-    70256, 70256, 70257, 70257, 70258, 70258, 70259, 70259, 70260, 70260, 
-    70260, 70260, 70261, 70261, 70261, 70261, 70262, 70262, 70262, 70262, 
-    70263, 70263, 70263, 70263, 70264, 70264, 70265, 70265, 70265, 70265, 
-    131874, 131874, 70266, 70266, 70266, 70266, 70267, 70267, 70267, 70267, 
-    70268, 70268, 131878, 131878, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 70269, 70269, 70269, 70269, 70270, 70270, 70271, 
-    70271, 70272, 70272, 131870, 70273, 70273, 70274, 70274, 70275, 70275, 
-    70276, 70276, 70276, 70276, 70277, 70277, 201350, 201350, 201353, 201353, 
-    201356, 201356, 201359, 201359, 201362, 201362, 201365, 201365, 201368, 
-    201368, 201368, 201371, 201371, 201371, 70302, 70302, 70302, 70302, 
-    201375, 201378, 201381, 201371, 201384, 135851, 135853, 135855, 135857, 
-    135859, 135861, 135863, 135865, 135867, 135869, 135871, 135873, 135875, 
-    135877, 135879, 135881, 135883, 135885, 135887, 135889, 135891, 135893, 
-    135895, 135897, 135899, 135901, 135903, 135905, 135907, 135909, 135911, 
-    135913, 135915, 135917, 135919, 135921, 135923, 135925, 135927, 135929, 
-    135931, 135933, 135935, 135937, 135939, 135941, 135943, 135945, 135947, 
-    135949, 135951, 135953, 135955, 135957, 135959, 135961, 135963, 135965, 
-    135967, 135969, 135971, 135973, 135975, 135977, 135979, 135981, 135983, 
-    135985, 135987, 135989, 135991, 135993, 135995, 135997, 135999, 136001, 
-    136003, 136005, 136007, 136009, 136011, 136013, 136015, 136017, 136019, 
-    136021, 136023, 136025, 136027, 201565, 201568, 201571, 201574, 201577, 
-    201580, 201583, 201586, 201381, 201589, 201371, 201384, 136056, 136058, 
-    135857, 136060, 135859, 135861, 136062, 136064, 135869, 136066, 135871, 
-    135873, 136068, 136070, 135877, 136072, 135879, 135881, 135939, 135941, 
-    135947, 135949, 135951, 135959, 135961, 135963, 135965, 135973, 135975, 
-    135977, 136074, 135985, 136076, 136078, 135997, 136080, 135999, 136001, 
-    136027, 136082, 136084, 136017, 136086, 136019, 136021, 201375, 201378, 
-    201624, 201381, 201627, 135851, 135853, 135855, 135857, 136094, 135863, 
-    135865, 135867, 135869, 136096, 135877, 135883, 135885, 135887, 135889, 
-    135891, 135895, 135897, 135899, 135901, 135903, 135905, 136098, 135907, 
-    135909, 135911, 135913, 135915, 135917, 135921, 135923, 135925, 135927, 
-    135929, 135931, 135933, 135935, 135937, 135943, 135945, 135953, 135955, 
-    135957, 135959, 135961, 135967, 135969, 135971, 135973, 136100, 135979, 
-    135981, 135983, 135985, 135991, 135993, 135995, 135997, 136102, 136003, 
-    136005, 136104, 136011, 136013, 136015, 136017, 136106, 201381, 201627, 
-    135857, 136094, 135869, 136096, 135877, 136108, 135903, 136110, 136112, 
-    136114, 135959, 135961, 135973, 135997, 136102, 136017, 136106, 201652, 
-    201655, 201658, 136125, 136127, 136129, 136131, 136133, 136135, 136137, 
-    136139, 136141, 136143, 136145, 136147, 136149, 136151, 136153, 136155, 
-    136157, 136159, 136161, 136163, 136165, 136167, 136169, 136112, 136171, 
-    136173, 136175, 136177, 136125, 136127, 136129, 136131, 136133, 136135, 
-    136137, 136139, 136141, 136143, 136145, 136147, 136149, 136151, 136153, 
-    136155, 136157, 136159, 136161, 136163, 136165, 136167, 136169, 136112, 
-    136171, 136173, 136175, 136177, 136165, 136167, 136169, 136112, 136110, 
-    136114, 135919, 135897, 135899, 135901, 136165, 136167, 136169, 135919, 
-    135921, 136179, 136179, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 201717, 201720, 201720, 201723, 201726, 
-    201729, 201732, 201735, 201738, 201738, 201741, 201744, 201747, 201750, 
-    201753, 201756, 201756, 201759, 201762, 201762, 201765, 201765, 201768, 
-    201771, 201771, 201774, 201777, 201777, 201780, 201780, 201783, 201786, 
-    201786, 201789, 201789, 201792, 201795, 201798, 201801, 201801, 201804, 
-    201807, 201810, 201813, 201816, 201816, 201819, 201822, 201825, 201828, 
-    201831, 201834, 201834, 201837, 201837, 201840, 201840, 201843, 201846, 
-    201849, 201852, 201855, 201858, 201861, -1, -1, 201864, 201867, 201870, 
-    201873, 201876, 201879, 201879, 201882, 201885, 201888, 201891, 201891, 
-    201894, 201897, 201900, 201903, 201906, 201909, 201912, 201915, 201918, 
-    201921, 201924, 201927, 201930, 201933, 201936, 201939, 201942, 201945, 
-    201948, 201951, 201954, 201957, 201819, 201825, 201960, 201963, 201966, 
-    201969, 201972, 201975, 201972, 201966, 201978, 201981, 201984, 201987, 
-    201990, 201975, 201798, 201768, 201993, 201996, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 201999, 202002, 267541, 267545, 267549, 267553, 267557, 267561, 
-    267565, 202033, 1185076, 529734, 267598, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133211, 70994, 70995, 70996, 
-    70996, 67715, 67716, 70997, 70998, 70999, 71000, 71001, 71002, 71003, 
-    71004, 67961, 67962, 71005, 71006, 71007, 71008, -1, -1, -1, -1, 133228, 
-    133228, 133228, 133228, 70996, 70996, 70996, 71009, 71010, 67674, -1, 
-    66157, 71011, 71012, 71013, 70994, 67715, 67716, 70997, 70998, 70999, 
-    71000, 71014, 71015, 71016, 67712, 71017, 71018, 71019, 67714, -1, 
-    71020, 71021, 71022, 71023, -1, -1, -1, -1, 136560, 136562, 136564, 
-    -1, 136566, -1, 136568, 136570, 136572, 136574, 136576, 136578, 136580, 
-    136582, 136584, 136586, 71052, 131856, 131856, 131858, 131858, 131860, 
-    131860, 131862, 131862, 131864, 131864, 131864, 131864, 71053, 71053, 
-    71054, 71054, 71054, 71054, 71055, 71055, 71056, 71056, 71056, 71056, 
-    71057, 71057, 71057, 71057, 71058, 71058, 71058, 71058, 71059, 71059, 
-    71059, 71059, 71060, 71060, 71060, 71060, 71061, 71061, 71062, 71062, 
-    71063, 71063, 71064, 71064, 71065, 71065, 71065, 71065, 71066, 71066, 
-    71066, 71066, 71067, 71067, 71067, 71067, 71068, 71068, 71068, 71068, 
-    71069, 71069, 71069, 71069, 71070, 71070, 71070, 71070, 71071, 71071, 
-    71071, 71071, 71072, 71072, 71072, 71072, 71073, 71073, 71073, 71073, 
-    71074, 71074, 71074, 71074, 71075, 71075, 71075, 71075, 71076, 71076, 
-    71076, 71076, 71077, 71077, 71077, 71077, 71078, 71078, 71078, 71078, 
-    71079, 71079, 71079, 71079, 71080, 71080, 70277, 70277, 71081, 71081, 
-    71081, 71081, 202154, 202154, 202157, 202157, 202160, 202160, 136627, 
-    136627, -1, -1, -1, -1, 71013, 71093, 71014, 71021, 71022, 71015, 71094, 
-    67715, 67716, 71016, 67712, 71009, 71017, 67674, 71095, 67704, 65549, 
-    65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 71011, 66157, 
-    71018, 67714, 71019, 71012, 71023, 68185, 67759, 67726, 67772, 67761, 
-    67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 
-    67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 
-    67756, 71096, 71020, 71097, 71098, 70996, 67649, 65539, 68194, 67861, 
-    67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 
-    67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 
-    66147, 66132, 68201, 70997, 71099, 70998, 71100, 71101, 71102, 71103, 
-    71005, 71006, 71010, 71104, 69066, 71105, 71106, 71107, 71108, 71109, 
-    71110, 71111, 71112, 71113, 71114, 69020, 69021, 69022, 69023, 69024, 
-    69025, 69026, 69027, 69028, 69029, 69030, 69031, 69032, 69033, 69034, 
-    69035, 69036, 69037, 69038, 69039, 69040, 69041, 69042, 69043, 69044, 
-    69045, 69046, 69047, 69048, 69049, 69050, 69051, 69052, 69053, 69054, 
-    69055, 69056, 69057, 69058, 69059, 69060, 69061, 69062, 69063, 71115, 
-    71116, 71117, 68610, 68559, 68560, 68561, 68562, 68563, 68564, 68565, 
-    68566, 68567, 68568, 68569, 68570, 68571, 68572, 68573, 68574, 68575, 
-    68576, 68577, 68578, 68579, 68580, 68581, 68582, 68583, 68584, 68585, 
-    68586, 68587, 68588, -1, -1, -1, 68589, 68590, 68591, 68592, 68593, 
-    68594, -1, -1, 68595, 68596, 68597, 68598, 68599, 68600, -1, -1, 68601, 
-    68602, 68603, 68604, 68605, 68606, -1, -1, 68607, 68608, 68609, -1, 
-    -1, -1, 71118, 71119, 71120, 131076, 71121, 71122, 71123, -1, 71124, 
-    71125, 71126, 71127, 71128, 71129, 71130, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 136667, 136669, 202207, 202210, 202213, 202216, 202219, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    136686, 136688, 202226, 202229, 202232, 202235, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 68185, 67759, 67726, 67772, 67761, 67762, 
-    68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 
-    67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 
-    65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 
-    68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 
-    68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 
-    67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 
-    68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 
-    68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, -1, 
-    67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 
-    65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 
-    67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 
-    67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 
-    68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 
-    67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 
-    68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 
-    68185, -1, 67726, 67772, -1, -1, 68186, -1, -1, 68187, 67758, -1, -1, 
-    67743, 68188, 67746, 67747, -1, 68189, 68190, 68191, 67819, 68192, 
-    67831, 68193, 67756, 65539, 68194, 67861, 67773, -1, 68195, -1, 66124, 
-    67705, 66126, 68196, -1, 67862, 67717, -1, 68197, 68198, 66127, 65892, 
-    68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 
-    67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 
-    67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 
-    67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 
-    66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 
-    66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 
-    67759, -1, 67772, 67761, 67762, 68186, -1, -1, 68187, 67758, 67742, 
-    67763, 67743, 68188, 67746, 67747, -1, 68189, 68190, 68191, 67819, 
-    68192, 67831, 68193, -1, 65539, 68194, 67861, 67773, 67760, 68195, 
-    67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 
-    68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 
-    68185, 67759, -1, 67772, 67761, 67762, 68186, -1, 67741, 68187, 67758, 
-    67742, 67763, -1, 68188, -1, -1, -1, 68189, 68190, 68191, 67819, 68192, 
-    67831, 68193, -1, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 
-    66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 
-    66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 
-    67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 
-    67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 
-    67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 
-    68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 
-    68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 
-    68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 
-    68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 
-    68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 
-    67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 
-    67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 
-    66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 
-    67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 
-    67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 
-    68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 
-    66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 
-    67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 
-    67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 
-    67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 
-    67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 
-    66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 
-    68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 
-    67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 
-    67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 
-    67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 
-    66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 
-    66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 
-    67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 
-    67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 
-    67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 
-    68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 
-    68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 
-    68201, -1, -1, -1, -1, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 
-    66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 
-    66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 
-    66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 
-    65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 
-    66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 
-    66208, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 
-    71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 
-    71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 
-    71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 
-    71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 
-    71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166, 
-    71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 
-    71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 
-    71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 
-    71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 
-    66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 
-    71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769, 
-    71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 
-    71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 
-    71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 
-    66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 
-    66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 
-    66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769, 71168, 71169, 
-    71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 
-    67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 
-    71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 
-    66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 
-    71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 
-    66207, 66210, 66208, -1, -1, -1, -1, 67704, 65549, 65542, 65543, 67706, 
-    67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 
-    67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 
-    67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 
-    67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 
-    67707, 67708, 67709, 67710, 67711, 71201, 71202, 71203, 71204, 71205, 
-    70085, 71206, 71207, 71208, 71209, 70086, 71210, 71211, 71212, 70087, 
-    71213, 71214, 71215, 71216, 71217, 71218, 71219, 71220, 71221, 71222, 
-    71223, 71224, 71225, 71226, 68234, 71227, 71228, 71229, 71230, 71231, 
-    71232, 71233, 71234, 70088, 70089, 71235, 71236, 71237, 69908, 71238, 
-    70090, 71239, 71240, 71241, 71242, 71242, 71242, 71243, 71244, 71245, 
-    71246, 71247, 71248, 71249, 71250, 71251, 71252, 71253, 71254, 71255, 
-    71256, 71257, 71258, 71259, 71260, 71260, 71261, 71262, 71263, 71264, 
-    71265, 70092, 71266, 71267, 71268, 70054, 71269, 71270, 71271, 71272, 
-    71273, 71274, 71275, 71276, 71277, 71278, 71279, 71280, 71281, 71282, 
-    71283, 71284, 71285, 71286, 71287, 71288, 71289, 71290, 71291, 71292, 
-    71293, 71294, 71294, 71295, 71296, 71297, 69904, 71298, 71299, 71300, 
-    71301, 71302, 68260, 71303, 71304, 68262, 71305, 71306, 71307, 71308, 
-    71309, 71310, 71311, 71312, 71313, 71314, 71315, 71316, 71317, 71318, 
-    71319, 71320, 71321, 71322, 71323, 71324, 71325, 69852, 71326, 68272, 
-    71327, 71327, 71328, 71329, 71329, 71330, 71331, 71332, 71333, 71334, 
-    71335, 71336, 71337, 71338, 71339, 71340, 71341, 71342, 70097, 71343, 
-    71344, 71345, 71346, 71347, 71346, 71348, 70099, 71349, 71350, 71351, 
-    71352, 70100, 69825, 71353, 71354, 71355, 71356, 71357, 71358, 71359, 
-    71360, 71361, 71362, 71363, 71364, 71365, 71366, 71367, 71368, 71369, 
-    71370, 71371, 71372, 71373, 71374, 70101, 71375, 71376, 71377, 71378, 
-    71379, 71380, 70103, 71381, 71382, 71383, 71384, 71385, 71386, 71387, 
-    71388, 69853, 71389, 71390, 71391, 71392, 71393, 71394, 71395, 71396, 
-    71397, 70104, 71398, 71399, 71400, 71401, 71402, 71403, 71404, 71405, 
-    71406, 71407, 71408, 71409, 71410, 71411, 71412, 71413, 71414, 71415, 
-    69921, 71416, 71417, 71418, 71419, 71420, 71421, 71422, 71423, 71424, 
-    71425, 71426, 70105, 70004, 71427, 71428, 71429, 71430, 71431, 71432, 
-    71433, 71434, 71435, 71436, 71437, 71438, 71439, 71440, 71441, 71442, 
-    71443, 71444, 71445, 71446, 71447, 71448, 71449, 71450, 71451, 71452, 
-    71453, 71454, 71455, 71456, 71457, 71458, 71459, 71460, 71461, 71462, 
-    71463, 71464, 71465, 71466, 71467, 71468, 71468, 71469, 71470, 71471, 
-    71472, 71473, 71474, 71475, 71476, 71477, 71478, 69907, 71479, 71480, 
-    71481, 71482, 71483, 71484, 71485, 71486, 71487, 71488, 71489, 71490, 
-    71491, 71492, 71492, 71493, 71494, 71495, 71496, 71497, 71498, 71499, 
-    69870, 71500, 71501, 71502, 70115, 71503, 71504, 70074, 71505, 71506, 
-    70118, 71507, 71508, 71509, 71510, 71510, 71511, 71512, 71513, 71514, 
-    71515, 71516, 71517, 71518, 71519, 71520, 71521, 71522, 71523, 71524, 
-    71525, 71526, 71527, 71528, 71529, 71530, 71531, 71532, 71533, 71534, 
-    71535, 71536, 71537, 70124, 71538, 71539, 71540, 71541, 71542, 71543, 
-    71544, 71545, 71546, 71547, 71548, 71549, 71550, 71551, 71552, 71553, 
-    71328, 71554, 71555, 71556, 71557, 71558, 71559, 71560, 71561, 71562, 
-    71563, 71564, 71565, 69924, 71566, 71567, 71568, 71569, 71570, 71571, 
-    70127, 71572, 71573, 71574, 71575, 71576, 71577, 71578, 71579, 71580, 
-    71581, 71582, 71583, 71584, 71585, 71586, 71587, 71588, 71589, 71590, 
-    71591, 69865, 71592, 71593, 71594, 71595, 71596, 71597, 71598, 71599, 
-    71600, 71601, 71602, 71603, 71604, 71605, 71606, 68362, 71607, 71608, 
-    71609, 71610, 71611, 71612, 71613, 71614, 71615, 71616, 71617, 71618, 
-    71619, 68369, 71620, 71621, 71622, 71623, 71624, 71625, 71626, 71627, 
-    71628, 71629, 71630, 71631, 71632, 71633, 71634, 71635, 71636, 71637, 
-    71638, 71639, 71640, 71641, 71642, 71643, 71644, 71645, 71646, 71647, 
-    71648, 71649, 71650, 71651, 71652, 71653, 71654, 71655, 71656, 71657, 
-    71658, 71659, 71660, 71661, 71662, 71663, 71663, 71664, 71665, 71666, 
-    71667, 71668, 71669, 71670, 71671, 71672, 71673, 71674, 71675, 71676, 
-    71677, 71678, 71679, 71680, 71681, 71682, 71683, 71684, 68417, 71685, 
-    68421, 71686, 71687, 71688, 71689, 68426, 71690, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-/*
- * List of decomposition sequences
- */
-
-static int decompList[] = {
-    32, 32, 776, 97, 32, 772, 50, 51, 32, 769, 956, 32, 807, 49, 111, 49, 
-    8260, 52, 49, 8260, 50, 51, 8260, 52, 65, 768, 65, 769, 65, 770, 65, 
-    771, 65, 776, 65, 778, 67, 807, 69, 768, 69, 769, 69, 770, 69, 776, 
-    73, 768, 73, 769, 73, 770, 73, 776, 78, 771, 79, 768, 79, 769, 79, 
-    770, 79, 771, 79, 776, 85, 768, 85, 769, 85, 770, 85, 776, 89, 769, 
-    97, 768, 97, 769, 97, 770, 97, 771, 97, 776, 97, 778, 99, 807, 101, 
-    768, 101, 769, 101, 770, 101, 776, 105, 768, 105, 769, 105, 770, 105, 
-    776, 110, 771, 111, 768, 111, 769, 111, 770, 111, 771, 111, 776, 117, 
-    768, 117, 769, 117, 770, 117, 776, 121, 769, 121, 776, 65, 772, 97, 
-    772, 65, 774, 97, 774, 65, 808, 97, 808, 67, 769, 99, 769, 67, 770, 
-    99, 770, 67, 775, 99, 775, 67, 780, 99, 780, 68, 780, 100, 780, 69, 
-    772, 101, 772, 69, 774, 101, 774, 69, 775, 101, 775, 69, 808, 101, 
-    808, 69, 780, 101, 780, 71, 770, 103, 770, 71, 774, 103, 774, 71, 775, 
-    103, 775, 71, 807, 103, 807, 72, 770, 104, 770, 73, 771, 105, 771, 
-    73, 772, 105, 772, 73, 774, 105, 774, 73, 808, 105, 808, 73, 775, 73, 
-    74, 105, 106, 74, 770, 106, 770, 75, 807, 107, 807, 76, 769, 108, 769, 
-    76, 807, 108, 807, 76, 780, 108, 780, 76, 183, 108, 183, 78, 769, 110, 
-    769, 78, 807, 110, 807, 78, 780, 110, 780, 700, 110, 79, 772, 111, 
-    772, 79, 774, 111, 774, 79, 779, 111, 779, 82, 769, 114, 769, 82, 807, 
-    114, 807, 82, 780, 114, 780, 83, 769, 115, 769, 83, 770, 115, 770, 
-    83, 807, 115, 807, 83, 780, 115, 780, 84, 807, 116, 807, 84, 780, 116, 
-    780, 85, 771, 117, 771, 85, 772, 117, 772, 85, 774, 117, 774, 85, 778, 
-    117, 778, 85, 779, 117, 779, 85, 808, 117, 808, 87, 770, 119, 770, 
-    89, 770, 121, 770, 89, 776, 90, 769, 122, 769, 90, 775, 122, 775, 90, 
-    780, 122, 780, 115, 79, 795, 111, 795, 85, 795, 117, 795, 68, 90, 780, 
-    68, 122, 780, 100, 122, 780, 76, 74, 76, 106, 108, 106, 78, 74, 78, 
-    106, 110, 106, 65, 780, 97, 780, 73, 780, 105, 780, 79, 780, 111, 780, 
-    85, 780, 117, 780, 85, 776, 772, 117, 776, 772, 85, 776, 769, 117, 
-    776, 769, 85, 776, 780, 117, 776, 780, 85, 776, 768, 117, 776, 768, 
-    65, 776, 772, 97, 776, 772, 65, 775, 772, 97, 775, 772, 198, 772, 230, 
-    772, 71, 780, 103, 780, 75, 780, 107, 780, 79, 808, 111, 808, 79, 808, 
-    772, 111, 808, 772, 439, 780, 658, 780, 106, 780, 68, 90, 68, 122, 
-    100, 122, 71, 769, 103, 769, 78, 768, 110, 768, 65, 778, 769, 97, 778, 
-    769, 198, 769, 230, 769, 216, 769, 248, 769, 65, 783, 97, 783, 65, 
-    785, 97, 785, 69, 783, 101, 783, 69, 785, 101, 785, 73, 783, 105, 783, 
-    73, 785, 105, 785, 79, 783, 111, 783, 79, 785, 111, 785, 82, 783, 114, 
-    783, 82, 785, 114, 785, 85, 783, 117, 783, 85, 785, 117, 785, 83, 806, 
-    115, 806, 84, 806, 116, 806, 72, 780, 104, 780, 65, 775, 97, 775, 69, 
-    807, 101, 807, 79, 776, 772, 111, 776, 772, 79, 771, 772, 111, 771, 
-    772, 79, 775, 111, 775, 79, 775, 772, 111, 775, 772, 89, 772, 121, 
-    772, 104, 614, 106, 114, 633, 635, 641, 119, 121, 32, 774, 32, 775, 
-    32, 778, 32, 808, 32, 771, 32, 779, 611, 108, 120, 661, 768, 769, 787, 
-    776, 769, 697, 32, 837, 59, 32, 776, 769, 913, 769, 183, 917, 769, 
-    919, 769, 921, 769, 927, 769, 933, 769, 937, 769, 953, 776, 769, 921, 
-    776, 933, 776, 945, 769, 949, 769, 951, 769, 953, 769, 965, 776, 769, 
-    953, 776, 965, 776, 959, 769, 965, 769, 969, 769, 946, 952, 933, 966, 
-    960, 954, 961, 962, 920, 949, 1045, 768, 1045, 776, 1043, 769, 1030, 
-    776, 1050, 769, 1048, 768, 1059, 774, 1048, 774, 1080, 774, 1077, 768, 
-    1077, 776, 1075, 769, 1110, 776, 1082, 769, 1080, 768, 1091, 774, 1140, 
-    783, 1141, 783, 1046, 774, 1078, 774, 1040, 774, 1072, 774, 1040, 776, 
-    1072, 776, 1045, 774, 1077, 774, 1240, 776, 1241, 776, 1046, 776, 1078, 
-    776, 1047, 776, 1079, 776, 1048, 772, 1080, 772, 1048, 776, 1080, 776, 
-    1054, 776, 1086, 776, 1256, 776, 1257, 776, 1069, 776, 1101, 776, 1059, 
-    772, 1091, 772, 1059, 776, 1091, 776, 1059, 779, 1091, 779, 1063, 776, 
-    1095, 776, 1067, 776, 1099, 776, 1381, 1410, 1575, 1619, 1575, 1620, 
-    1608, 1620, 1575, 1621, 1610, 1620, 1575, 1652, 1608, 1652, 1735, 1652, 
-    1610, 1652, 1749, 1620, 1729, 1620, 1746, 1620, 2344, 2364, 2352, 2364, 
-    2355, 2364, 2325, 2364, 2326, 2364, 2327, 2364, 2332, 2364, 2337, 2364, 
-    2338, 2364, 2347, 2364, 2351, 2364, 2503, 2494, 2503, 2519, 2465, 2492, 
-    2466, 2492, 2479, 2492, 2610, 2620, 2616, 2620, 2582, 2620, 2583, 2620, 
-    2588, 2620, 2603, 2620, 2887, 2902, 2887, 2878, 2887, 2903, 2849, 2876, 
-    2850, 2876, 2962, 3031, 3014, 3006, 3015, 3006, 3014, 3031, 3142, 3158, 
-    3263, 3285, 3270, 3285, 3270, 3286, 3270, 3266, 3270, 3266, 3285, 3398, 
-    3390, 3399, 3390, 3398, 3415, 3545, 3530, 3545, 3535, 3545, 3535, 3530, 
-    3545, 3551, 3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, 3851, 3906, 
-    4023, 3916, 4023, 3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021, 3953, 
-    3954, 3953, 3956, 4018, 3968, 4018, 3953, 3968, 4019, 3968, 4019, 3953, 
-    3968, 3953, 3968, 3986, 4023, 3996, 4023, 4001, 4023, 4006, 4023, 4011, 
-    4023, 3984, 4021, 4133, 4142, 65, 805, 97, 805, 66, 775, 98, 775, 66, 
-    803, 98, 803, 66, 817, 98, 817, 67, 807, 769, 99, 807, 769, 68, 775, 
-    100, 775, 68, 803, 100, 803, 68, 817, 100, 817, 68, 807, 100, 807, 
-    68, 813, 100, 813, 69, 772, 768, 101, 772, 768, 69, 772, 769, 101, 
-    772, 769, 69, 813, 101, 813, 69, 816, 101, 816, 69, 807, 774, 101, 
-    807, 774, 70, 775, 102, 775, 71, 772, 103, 772, 72, 775, 104, 775, 
-    72, 803, 104, 803, 72, 776, 104, 776, 72, 807, 104, 807, 72, 814, 104, 
-    814, 73, 816, 105, 816, 73, 776, 769, 105, 776, 769, 75, 769, 107, 
-    769, 75, 803, 107, 803, 75, 817, 107, 817, 76, 803, 108, 803, 76, 803, 
-    772, 108, 803, 772, 76, 817, 108, 817, 76, 813, 108, 813, 77, 769, 
-    109, 769, 77, 775, 109, 775, 77, 803, 109, 803, 78, 775, 110, 775, 
-    78, 803, 110, 803, 78, 817, 110, 817, 78, 813, 110, 813, 79, 771, 769, 
-    111, 771, 769, 79, 771, 776, 111, 771, 776, 79, 772, 768, 111, 772, 
-    768, 79, 772, 769, 111, 772, 769, 80, 769, 112, 769, 80, 775, 112, 
-    775, 82, 775, 114, 775, 82, 803, 114, 803, 82, 803, 772, 114, 803, 
-    772, 82, 817, 114, 817, 83, 775, 115, 775, 83, 803, 115, 803, 83, 769, 
-    775, 115, 769, 775, 83, 780, 775, 115, 780, 775, 83, 803, 775, 115, 
-    803, 775, 84, 775, 116, 775, 84, 803, 116, 803, 84, 817, 116, 817, 
-    84, 813, 116, 813, 85, 804, 117, 804, 85, 816, 117, 816, 85, 813, 117, 
-    813, 85, 771, 769, 117, 771, 769, 85, 772, 776, 117, 772, 776, 86, 
-    771, 118, 771, 86, 803, 118, 803, 87, 768, 119, 768, 87, 769, 119, 
-    769, 87, 776, 119, 776, 87, 775, 119, 775, 87, 803, 119, 803, 88, 775, 
-    120, 775, 88, 776, 120, 776, 89, 775, 121, 775, 90, 770, 122, 770, 
-    90, 803, 122, 803, 90, 817, 122, 817, 104, 817, 116, 776, 119, 778, 
-    121, 778, 97, 702, 65, 803, 97, 803, 65, 777, 97, 777, 65, 770, 769, 
-    97, 770, 769, 65, 770, 768, 97, 770, 768, 65, 770, 777, 97, 770, 777, 
-    65, 770, 771, 97, 770, 771, 65, 803, 770, 97, 803, 770, 65, 774, 769, 
-    97, 774, 769, 65, 774, 768, 97, 774, 768, 65, 774, 777, 97, 774, 777, 
-    65, 774, 771, 97, 774, 771, 65, 803, 774, 97, 803, 774, 69, 803, 101, 
-    803, 69, 777, 101, 777, 69, 771, 101, 771, 69, 770, 769, 101, 770, 
-    769, 69, 770, 768, 101, 770, 768, 69, 770, 777, 101, 770, 777, 69, 
-    770, 771, 101, 770, 771, 69, 803, 770, 101, 803, 770, 73, 777, 105, 
-    777, 73, 803, 105, 803, 79, 803, 111, 803, 79, 777, 111, 777, 79, 770, 
-    769, 111, 770, 769, 79, 770, 768, 111, 770, 768, 79, 770, 777, 111, 
-    770, 777, 79, 770, 771, 111, 770, 771, 79, 803, 770, 111, 803, 770, 
-    79, 795, 769, 111, 795, 769, 79, 795, 768, 111, 795, 768, 79, 795, 
-    777, 111, 795, 777, 79, 795, 771, 111, 795, 771, 79, 795, 803, 111, 
-    795, 803, 85, 803, 117, 803, 85, 777, 117, 777, 85, 795, 769, 117, 
-    795, 769, 85, 795, 768, 117, 795, 768, 85, 795, 777, 117, 795, 777, 
-    85, 795, 771, 117, 795, 771, 85, 795, 803, 117, 795, 803, 89, 768, 
-    121, 768, 89, 803, 121, 803, 89, 777, 121, 777, 89, 771, 121, 771, 
-    945, 787, 945, 788, 945, 787, 768, 945, 788, 768, 945, 787, 769, 945, 
-    788, 769, 945, 787, 834, 945, 788, 834, 913, 787, 913, 788, 913, 787, 
-    768, 913, 788, 768, 913, 787, 769, 913, 788, 769, 913, 787, 834, 913, 
-    788, 834, 949, 787, 949, 788, 949, 787, 768, 949, 788, 768, 949, 787, 
-    769, 949, 788, 769, 917, 787, 917, 788, 917, 787, 768, 917, 788, 768, 
-    917, 787, 769, 917, 788, 769, 951, 787, 951, 788, 951, 787, 768, 951, 
-    788, 768, 951, 787, 769, 951, 788, 769, 951, 787, 834, 951, 788, 834, 
-    919, 787, 919, 788, 919, 787, 768, 919, 788, 768, 919, 787, 769, 919, 
-    788, 769, 919, 787, 834, 919, 788, 834, 953, 787, 953, 788, 953, 787, 
-    768, 953, 788, 768, 953, 787, 769, 953, 788, 769, 953, 787, 834, 953, 
-    788, 834, 921, 787, 921, 788, 921, 787, 768, 921, 788, 768, 921, 787, 
-    769, 921, 788, 769, 921, 787, 834, 921, 788, 834, 959, 787, 959, 788, 
-    959, 787, 768, 959, 788, 768, 959, 787, 769, 959, 788, 769, 927, 787, 
-    927, 788, 927, 787, 768, 927, 788, 768, 927, 787, 769, 927, 788, 769, 
-    965, 787, 965, 788, 965, 787, 768, 965, 788, 768, 965, 787, 769, 965, 
-    788, 769, 965, 787, 834, 965, 788, 834, 933, 788, 933, 788, 768, 933, 
-    788, 769, 933, 788, 834, 969, 787, 969, 788, 969, 787, 768, 969, 788, 
-    768, 969, 787, 769, 969, 788, 769, 969, 787, 834, 969, 788, 834, 937, 
-    787, 937, 788, 937, 787, 768, 937, 788, 768, 937, 787, 769, 937, 788, 
-    769, 937, 787, 834, 937, 788, 834, 945, 768, 949, 768, 951, 768, 953, 
-    768, 959, 768, 965, 768, 969, 768, 945, 787, 837, 945, 788, 837, 945, 
-    787, 768, 837, 945, 788, 768, 837, 945, 787, 769, 837, 945, 788, 769, 
-    837, 945, 787, 834, 837, 945, 788, 834, 837, 913, 787, 837, 913, 788, 
-    837, 913, 787, 768, 837, 913, 788, 768, 837, 913, 787, 769, 837, 913, 
-    788, 769, 837, 913, 787, 834, 837, 913, 788, 834, 837, 951, 787, 837, 
-    951, 788, 837, 951, 787, 768, 837, 951, 788, 768, 837, 951, 787, 769, 
-    837, 951, 788, 769, 837, 951, 787, 834, 837, 951, 788, 834, 837, 919, 
-    787, 837, 919, 788, 837, 919, 787, 768, 837, 919, 788, 768, 837, 919, 
-    787, 769, 837, 919, 788, 769, 837, 919, 787, 834, 837, 919, 788, 834, 
-    837, 969, 787, 837, 969, 788, 837, 969, 787, 768, 837, 969, 788, 768, 
-    837, 969, 787, 769, 837, 969, 788, 769, 837, 969, 787, 834, 837, 969, 
-    788, 834, 837, 937, 787, 837, 937, 788, 837, 937, 787, 768, 837, 937, 
-    788, 768, 837, 937, 787, 769, 837, 937, 788, 769, 837, 937, 787, 834, 
-    837, 937, 788, 834, 837, 945, 774, 945, 772, 945, 768, 837, 945, 837, 
-    945, 769, 837, 945, 834, 945, 834, 837, 913, 774, 913, 772, 913, 768, 
-    913, 837, 32, 787, 953, 32, 834, 32, 776, 834, 951, 768, 837, 951, 
-    837, 951, 769, 837, 951, 834, 951, 834, 837, 917, 768, 919, 768, 919, 
-    837, 32, 787, 768, 32, 787, 769, 32, 787, 834, 953, 774, 953, 772, 
-    953, 776, 768, 953, 834, 953, 776, 834, 921, 774, 921, 772, 921, 768, 
-    32, 788, 768, 32, 788, 769, 32, 788, 834, 965, 774, 965, 772, 965, 
-    776, 768, 961, 787, 961, 788, 965, 834, 965, 776, 834, 933, 774, 933, 
-    772, 933, 768, 929, 788, 32, 776, 768, 96, 969, 768, 837, 969, 837, 
-    969, 769, 837, 969, 834, 969, 834, 837, 927, 768, 937, 768, 937, 837, 
-    32, 788, 8208, 32, 819, 46, 46, 46, 46, 46, 46, 8242, 8242, 8242, 8242, 
-    8242, 8245, 8245, 8245, 8245, 8245, 33, 33, 32, 773, 63, 63, 63, 33, 
-    33, 63, 8242, 8242, 8242, 8242, 48, 105, 52, 53, 54, 55, 56, 57, 43, 
-    8722, 61, 40, 41, 110, 82, 115, 97, 47, 99, 97, 47, 115, 67, 176, 67, 
-    99, 47, 111, 99, 47, 117, 400, 176, 70, 103, 72, 295, 73, 76, 78, 78, 
-    111, 80, 81, 82, 83, 77, 84, 69, 76, 84, 77, 90, 937, 75, 66, 101, 
-    69, 70, 77, 1488, 1489, 1490, 1491, 947, 915, 928, 8721, 68, 100, 49, 
-    8260, 51, 50, 8260, 51, 49, 8260, 53, 50, 8260, 53, 51, 8260, 53, 52, 
-    8260, 53, 49, 8260, 54, 53, 8260, 54, 49, 8260, 56, 51, 8260, 56, 53, 
-    8260, 56, 55, 8260, 56, 49, 8260, 73, 73, 73, 73, 73, 73, 86, 86, 86, 
-    73, 86, 73, 73, 86, 73, 73, 73, 73, 88, 88, 88, 73, 88, 73, 73, 105, 
-    105, 105, 105, 105, 105, 118, 118, 118, 105, 118, 105, 105, 118, 105, 
-    105, 105, 105, 120, 120, 105, 120, 105, 105, 99, 109, 8592, 824, 8594, 
-    824, 8596, 824, 8656, 824, 8660, 824, 8658, 824, 8707, 824, 8712, 824, 
-    8715, 824, 8739, 824, 8741, 824, 8747, 8747, 8747, 8747, 8747, 8750, 
-    8750, 8750, 8750, 8750, 8764, 824, 8771, 824, 8773, 824, 8776, 824, 
-    61, 824, 8801, 824, 8781, 824, 60, 824, 62, 824, 8804, 824, 8805, 824, 
-    8818, 824, 8819, 824, 8822, 824, 8823, 824, 8826, 824, 8827, 824, 8834, 
-    824, 8835, 824, 8838, 824, 8839, 824, 8866, 824, 8872, 824, 8873, 824, 
-    8875, 824, 8828, 824, 8829, 824, 8849, 824, 8850, 824, 8882, 824, 8883, 
-    824, 8884, 824, 8885, 824, 12296, 12297, 49, 48, 49, 49, 49, 50, 49, 
-    51, 49, 52, 49, 53, 49, 54, 49, 55, 49, 56, 49, 57, 50, 48, 40, 49, 
-    41, 40, 50, 41, 40, 51, 41, 40, 52, 41, 40, 53, 41, 40, 54, 41, 40, 
-    55, 41, 40, 56, 41, 40, 57, 41, 40, 49, 48, 41, 40, 49, 49, 41, 40, 
-    49, 50, 41, 40, 49, 51, 41, 40, 49, 52, 41, 40, 49, 53, 41, 40, 49, 
-    54, 41, 40, 49, 55, 41, 40, 49, 56, 41, 40, 49, 57, 41, 40, 50, 48, 
-    41, 49, 46, 50, 46, 51, 46, 52, 46, 53, 46, 54, 46, 55, 46, 56, 46, 
-    57, 46, 49, 48, 46, 49, 49, 46, 49, 50, 46, 49, 51, 46, 49, 52, 46, 
-    49, 53, 46, 49, 54, 46, 49, 55, 46, 49, 56, 46, 49, 57, 46, 50, 48, 
-    46, 40, 97, 41, 40, 98, 41, 40, 99, 41, 40, 100, 41, 40, 101, 41, 40, 
-    102, 41, 40, 103, 41, 40, 104, 41, 40, 105, 41, 40, 106, 41, 40, 107, 
-    41, 40, 108, 41, 40, 109, 41, 40, 110, 41, 40, 111, 41, 40, 112, 41, 
-    40, 113, 41, 40, 114, 41, 40, 115, 41, 40, 116, 41, 40, 117, 41, 40, 
-    118, 41, 40, 119, 41, 40, 120, 41, 40, 121, 41, 40, 122, 41, 65, 71, 
-    74, 79, 83, 84, 85, 87, 89, 98, 102, 107, 112, 113, 116, 117, 122, 
-    8747, 8747, 8747, 8747, 58, 58, 61, 61, 61, 61, 61, 61, 10973, 824, 
-    27597, 40863, 19968, 20008, 20022, 20031, 20057, 20101, 20108, 20128, 
-    20154, 20799, 20837, 20843, 20866, 20886, 20907, 20960, 20981, 20992, 
-    21147, 21241, 21269, 21274, 21304, 21313, 21340, 21353, 21378, 21430, 
-    21448, 21475, 22231, 22303, 22763, 22786, 22794, 22805, 22823, 22899, 
-    23376, 23424, 23544, 23567, 23586, 23608, 23662, 23665, 24027, 24037, 
-    24049, 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339, 24400, 
-    24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991, 26007, 
-    26020, 26041, 26080, 26085, 26352, 26376, 26408, 27424, 27490, 27513, 
-    27571, 27595, 27604, 27611, 27663, 27668, 27700, 28779, 29226, 29238, 
-    29243, 29247, 29255, 29273, 29275, 29356, 29572, 29577, 29916, 29926, 
-    29976, 29983, 29992, 30000, 30091, 30098, 30326, 30333, 30382, 30399, 
-    30446, 30683, 30690, 30707, 31034, 31160, 31166, 31348, 31435, 31481, 
-    31859, 31992, 32566, 32593, 32650, 32701, 32769, 32780, 32786, 32819, 
-    32895, 32905, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 
-    33394, 33400, 34381, 34411, 34880, 34892, 34915, 35198, 35211, 35282, 
-    35328, 35895, 35910, 35925, 35960, 35997, 36196, 36208, 36275, 36523, 
-    36554, 36763, 36784, 36789, 37009, 37193, 37318, 37324, 37329, 38263, 
-    38272, 38428, 38582, 38585, 38632, 38737, 38750, 38754, 38761, 38859, 
-    38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 39340, 39592, 
-    39640, 39647, 39717, 39727, 39730, 39740, 39770, 40165, 40565, 40575, 
-    40613, 40635, 40643, 40653, 40657, 40697, 40701, 40718, 40723, 40736, 
-    40763, 40778, 40786, 40845, 40860, 40864, 12306, 21316, 21317, 12363, 
-    12441, 12365, 12441, 12367, 12441, 12369, 12441, 12371, 12441, 12373, 
-    12441, 12375, 12441, 12377, 12441, 12379, 12441, 12381, 12441, 12383, 
-    12441, 12385, 12441, 12388, 12441, 12390, 12441, 12392, 12441, 12399, 
-    12441, 12399, 12442, 12402, 12441, 12402, 12442, 12405, 12441, 12405, 
-    12442, 12408, 12441, 12408, 12442, 12411, 12441, 12411, 12442, 12358, 
-    12441, 32, 12441, 32, 12442, 12445, 12441, 12424, 12426, 12459, 12441, 
-    12461, 12441, 12463, 12441, 12465, 12441, 12467, 12441, 12469, 12441, 
-    12471, 12441, 12473, 12441, 12475, 12441, 12477, 12441, 12479, 12441, 
-    12481, 12441, 12484, 12441, 12486, 12441, 12488, 12441, 12495, 12441, 
-    12495, 12442, 12498, 12441, 12498, 12442, 12501, 12441, 12501, 12442, 
-    12504, 12441, 12504, 12442, 12507, 12441, 12507, 12442, 12454, 12441, 
-    12527, 12441, 12528, 12441, 12529, 12441, 12530, 12441, 12541, 12441, 
-    12467, 12488, 4352, 4353, 4522, 4354, 4524, 4525, 4355, 4356, 4357, 
-    4528, 4529, 4530, 4531, 4532, 4533, 4378, 4358, 4359, 4360, 4385, 4361, 
-    4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4449, 4450, 4451, 
-    4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460, 4461, 4462, 4463, 
-    4464, 4465, 4466, 4467, 4468, 4469, 4448, 4372, 4373, 4551, 4552, 4556, 
-    4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382, 4384, 4386, 4387, 
-    4391, 4393, 4395, 4396, 4397, 4398, 4399, 4402, 4406, 4416, 4423, 4428, 
-    4593, 4594, 4439, 4440, 4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510, 
-    4513, 19977, 22235, 19978, 20013, 19979, 30002, 19993, 19969, 22825, 
-    22320, 40, 4352, 41, 40, 4354, 41, 40, 4355, 41, 40, 4357, 41, 40, 
-    4358, 41, 40, 4359, 41, 40, 4361, 41, 40, 4363, 41, 40, 4364, 41, 40, 
-    4366, 41, 40, 4367, 41, 40, 4368, 41, 40, 4369, 41, 40, 4370, 41, 40, 
-    4352, 4449, 41, 40, 4354, 4449, 41, 40, 4355, 4449, 41, 40, 4357, 4449, 
-    41, 40, 4358, 4449, 41, 40, 4359, 4449, 41, 40, 4361, 4449, 41, 40, 
-    4363, 4449, 41, 40, 4364, 4449, 41, 40, 4366, 4449, 41, 40, 4367, 4449, 
-    41, 40, 4368, 4449, 41, 40, 4369, 4449, 41, 40, 4370, 4449, 41, 40, 
-    4364, 4462, 41, 40, 19968, 41, 40, 20108, 41, 40, 19977, 41, 40, 22235, 
-    41, 40, 20116, 41, 40, 20845, 41, 40, 19971, 41, 40, 20843, 41, 40, 
-    20061, 41, 40, 21313, 41, 40, 26376, 41, 40, 28779, 41, 40, 27700, 
-    41, 40, 26408, 41, 40, 37329, 41, 40, 22303, 41, 40, 26085, 41, 40, 
-    26666, 41, 40, 26377, 41, 40, 31038, 41, 40, 21517, 41, 40, 29305, 
-    41, 40, 36001, 41, 40, 31069, 41, 40, 21172, 41, 40, 20195, 41, 40, 
-    21628, 41, 40, 23398, 41, 40, 30435, 41, 40, 20225, 41, 40, 36039, 
-    41, 40, 21332, 41, 40, 31085, 41, 40, 20241, 41, 40, 33258, 41, 40, 
-    33267, 41, 50, 49, 50, 50, 50, 51, 50, 52, 50, 53, 50, 54, 50, 55, 
-    50, 56, 50, 57, 51, 48, 51, 49, 51, 50, 51, 51, 51, 52, 51, 53, 4352, 
-    4449, 4354, 4449, 4355, 4449, 4357, 4449, 4358, 4449, 4359, 4449, 4361, 
-    4449, 4363, 4449, 4364, 4449, 4366, 4449, 4367, 4449, 4368, 4449, 4369, 
-    4449, 4370, 4449, 20116, 20845, 19971, 20061, 26666, 26377, 31038, 
-    21517, 29305, 36001, 31069, 21172, 31192, 30007, 36969, 20778, 21360, 
-    27880, 38917, 20241, 20889, 27491, 24038, 21491, 21307, 23447, 23398, 
-    30435, 20225, 36039, 21332, 22812, 51, 54, 51, 55, 51, 56, 51, 57, 
-    52, 48, 52, 49, 52, 50, 52, 51, 52, 52, 52, 53, 52, 54, 52, 55, 52, 
-    56, 52, 57, 53, 48, 49, 26376, 50, 26376, 51, 26376, 52, 26376, 53, 
-    26376, 54, 26376, 55, 26376, 56, 26376, 57, 26376, 49, 48, 26376, 49, 
-    49, 26376, 49, 50, 26376, 12450, 12452, 12454, 12456, 12458, 12459, 
-    12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, 12477, 12479, 
-    12481, 12484, 12486, 12488, 12490, 12491, 12492, 12493, 12494, 12495, 
-    12498, 12501, 12504, 12507, 12510, 12511, 12512, 12513, 12514, 12516, 
-    12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12528, 12529, 
-    12530, 12450, 12495, 12442, 12540, 12488, 12450, 12523, 12501, 12449, 
-    12450, 12531, 12504, 12442, 12450, 12450, 12540, 12523, 12452, 12491, 
-    12531, 12463, 12441, 12452, 12531, 12481, 12454, 12457, 12531, 12456, 
-    12473, 12463, 12540, 12488, 12441, 12456, 12540, 12459, 12540, 12458, 
-    12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522, 12459, 12521, 
-    12483, 12488, 12459, 12525, 12522, 12540, 12459, 12441, 12525, 12531, 
-    12459, 12441, 12531, 12510, 12461, 12441, 12459, 12441, 12461, 12441, 
-    12491, 12540, 12461, 12517, 12522, 12540, 12461, 12441, 12523, 12479, 
-    12441, 12540, 12461, 12525, 12461, 12525, 12463, 12441, 12521, 12512, 
-    12461, 12525, 12513, 12540, 12488, 12523, 12461, 12525, 12527, 12483, 
-    12488, 12463, 12441, 12521, 12512, 12463, 12441, 12521, 12512, 12488, 
-    12531, 12463, 12523, 12475, 12441, 12452, 12525, 12463, 12525, 12540, 
-    12493, 12465, 12540, 12473, 12467, 12523, 12490, 12467, 12540, 12507, 
-    12442, 12469, 12452, 12463, 12523, 12469, 12531, 12481, 12540, 12512, 
-    12471, 12522, 12531, 12463, 12441, 12475, 12531, 12481, 12475, 12531, 
-    12488, 12479, 12441, 12540, 12473, 12486, 12441, 12471, 12488, 12441, 
-    12523, 12488, 12531, 12490, 12494, 12494, 12483, 12488, 12495, 12452, 
-    12484, 12495, 12442, 12540, 12475, 12531, 12488, 12495, 12442, 12540, 
-    12484, 12495, 12441, 12540, 12524, 12523, 12498, 12442, 12450, 12473, 
-    12488, 12523, 12498, 12442, 12463, 12523, 12498, 12442, 12467, 12498, 
-    12441, 12523, 12501, 12449, 12521, 12483, 12488, 12441, 12501, 12451, 
-    12540, 12488, 12501, 12441, 12483, 12471, 12455, 12523, 12501, 12521, 
-    12531, 12504, 12463, 12479, 12540, 12523, 12504, 12442, 12477, 12504, 
-    12442, 12491, 12498, 12504, 12523, 12484, 12504, 12442, 12531, 12473, 
-    12504, 12442, 12540, 12471, 12441, 12504, 12441, 12540, 12479, 12507, 
-    12442, 12452, 12531, 12488, 12507, 12441, 12523, 12488, 12507, 12531, 
-    12507, 12442, 12531, 12488, 12441, 12507, 12540, 12523, 12507, 12540, 
-    12531, 12510, 12452, 12463, 12525, 12510, 12452, 12523, 12510, 12483, 
-    12495, 12510, 12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511, 
-    12463, 12525, 12531, 12511, 12522, 12511, 12522, 12495, 12441, 12540, 
-    12523, 12513, 12459, 12441, 12513, 12459, 12441, 12488, 12531, 12513, 
-    12540, 12488, 12523, 12516, 12540, 12488, 12441, 12516, 12540, 12523, 
-    12518, 12450, 12531, 12522, 12483, 12488, 12523, 12522, 12521, 12523, 
-    12498, 12442, 12540, 12523, 12540, 12501, 12441, 12523, 12524, 12512, 
-    12524, 12531, 12488, 12465, 12441, 12531, 12527, 12483, 12488, 48, 
-    28857, 49, 28857, 50, 28857, 51, 28857, 52, 28857, 53, 28857, 54, 28857, 
-    55, 28857, 56, 28857, 57, 28857, 49, 48, 28857, 49, 49, 28857, 49, 
-    50, 28857, 49, 51, 28857, 49, 52, 28857, 49, 53, 28857, 49, 54, 28857, 
-    49, 55, 28857, 49, 56, 28857, 49, 57, 28857, 50, 48, 28857, 50, 49, 
-    28857, 50, 50, 28857, 50, 51, 28857, 50, 52, 28857, 104, 80, 97, 100, 
-    97, 65, 85, 98, 97, 114, 111, 86, 112, 99, 24179, 25104, 26157, 21644, 
-    22823, 27491, 26126, 27835, 26666, 24335, 20250, 31038, 112, 65, 110, 
-    65, 956, 65, 109, 65, 107, 65, 75, 66, 77, 66, 71, 66, 99, 97, 108, 
-    107, 99, 97, 108, 112, 70, 110, 70, 956, 70, 956, 103, 109, 103, 107, 
-    103, 72, 122, 107, 72, 122, 77, 72, 122, 71, 72, 122, 84, 72, 122, 
-    956, 108, 109, 108, 100, 108, 107, 108, 102, 109, 110, 109, 956, 109, 
-    109, 109, 99, 109, 107, 109, 109, 109, 50, 99, 109, 50, 109, 50, 107, 
-    109, 50, 109, 109, 51, 99, 109, 51, 109, 51, 107, 109, 51, 109, 8725, 
-    115, 109, 8725, 115, 50, 80, 97, 107, 80, 97, 77, 80, 97, 71, 80, 97, 
-    114, 97, 100, 114, 97, 100, 8725, 115, 114, 97, 100, 8725, 115, 50, 
-    112, 115, 110, 115, 956, 115, 109, 115, 112, 86, 110, 86, 956, 86, 
-    109, 86, 107, 86, 77, 86, 112, 87, 110, 87, 956, 87, 109, 87, 107, 
-    87, 77, 87, 107, 937, 77, 937, 97, 46, 109, 46, 66, 113, 99, 99, 99, 
-    100, 67, 8725, 107, 103, 67, 111, 46, 100, 66, 71, 121, 104, 97, 72, 
-    80, 105, 110, 75, 75, 75, 77, 107, 116, 108, 109, 108, 110, 108, 111, 
-    103, 108, 120, 109, 98, 109, 105, 108, 109, 111, 108, 80, 72, 112, 
-    46, 109, 46, 80, 80, 77, 80, 82, 115, 114, 83, 118, 87, 98, 49, 26085, 
-    50, 26085, 51, 26085, 52, 26085, 53, 26085, 54, 26085, 55, 26085, 56, 
-    26085, 57, 26085, 49, 48, 26085, 49, 49, 26085, 49, 50, 26085, 49, 
-    51, 26085, 49, 52, 26085, 49, 53, 26085, 49, 54, 26085, 49, 55, 26085, 
-    49, 56, 26085, 49, 57, 26085, 50, 48, 26085, 50, 49, 26085, 50, 50, 
-    26085, 50, 51, 26085, 50, 52, 26085, 50, 53, 26085, 50, 54, 26085, 
-    50, 55, 26085, 50, 56, 26085, 50, 57, 26085, 51, 48, 26085, 51, 49, 
-    26085, 35912, 26356, 36040, 28369, 20018, 21477, 22865, 21895, 22856, 
-    25078, 30313, 32645, 34367, 34746, 35064, 37007, 27138, 27931, 28889, 
-    29662, 33853, 37226, 39409, 20098, 21365, 27396, 29211, 34349, 40478, 
-    23888, 28651, 34253, 35172, 25289, 33240, 34847, 24266, 26391, 28010, 
-    29436, 37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, 34310, 
-    34396, 36335, 38706, 39791, 40442, 30860, 31103, 32160, 33737, 37636, 
-    35542, 22751, 24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744, 
-    23650, 27155, 28122, 28431, 32047, 32311, 38475, 21202, 32907, 20956, 
-    20940, 31260, 32190, 33777, 38517, 35712, 25295, 35582, 20025, 23527, 
-    24594, 29575, 30064, 21271, 30971, 20415, 24489, 19981, 27852, 25976, 
-    32034, 21443, 22622, 30465, 33865, 35498, 27578, 27784, 25342, 33509, 
-    25504, 30053, 20142, 20841, 20937, 26753, 31975, 33391, 35538, 37327, 
-    21237, 21570, 24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654, 
-    26310, 27511, 36706, 24180, 24976, 25088, 25754, 28451, 29001, 29833, 
-    31178, 32244, 32879, 36646, 34030, 36899, 37706, 21015, 21155, 21693, 
-    28872, 35010, 24265, 24565, 25467, 27566, 31806, 29557, 20196, 22265, 
-    23994, 24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, 38936, 
-    20363, 31150, 37300, 38584, 24801, 20102, 20698, 23534, 23615, 26009, 
-    29134, 30274, 34044, 36988, 26248, 38446, 21129, 26491, 26611, 27969, 
-    28316, 29705, 30041, 30827, 32016, 39006, 25134, 38520, 20523, 23833, 
-    28138, 36650, 24459, 24900, 26647, 38534, 21033, 21519, 23653, 26131, 
-    26446, 26792, 27877, 29702, 30178, 32633, 35023, 35041, 38626, 21311, 
-    28346, 21533, 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107, 
-    33256, 31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050, 20999, 
-    24230, 25299, 31958, 23429, 27934, 26292, 36667, 38477, 24275, 20800, 
-    21952, 22618, 26228, 20958, 29482, 30410, 31036, 31070, 31077, 31119, 
-    38742, 31934, 34322, 35576, 36920, 37117, 39151, 39164, 39208, 40372, 
-    20398, 20711, 20813, 21193, 21220, 21329, 21917, 22022, 22120, 22592, 
-    22696, 23652, 24724, 24936, 24974, 25074, 25935, 26082, 26257, 26757, 
-    28023, 28186, 28450, 29038, 29227, 29730, 30865, 31049, 31048, 31056, 
-    31062, 31117, 31118, 31296, 31361, 31680, 32265, 32321, 32626, 32773, 
-    33261, 33401, 33879, 35088, 35222, 35585, 35641, 36051, 36104, 36790, 
-    38627, 38911, 38971, 102, 102, 102, 105, 102, 108, 102, 102, 105, 102, 
-    102, 108, 115, 116, 1396, 1398, 1396, 1381, 1396, 1387, 1406, 1398, 
-    1396, 1389, 1497, 1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, 1512, 
-    1514, 1513, 1473, 1513, 1474, 1513, 1468, 1473, 1513, 1468, 1474, 1488, 
-    1463, 1488, 1464, 1488, 1468, 1489, 1468, 1490, 1468, 1491, 1468, 1492, 
-    1468, 1493, 1468, 1494, 1468, 1496, 1468, 1497, 1468, 1498, 1468, 1499, 
-    1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468, 1507, 1468, 1508, 
-    1468, 1510, 1468, 1511, 1468, 1512, 1468, 1513, 1468, 1514, 1468, 1493, 
-    1465, 1489, 1471, 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1659, 1662, 
-    1664, 1658, 1663, 1657, 1700, 1702, 1668, 1667, 1670, 1671, 1677, 1676, 
-    1678, 1672, 1688, 1681, 1705, 1711, 1715, 1713, 1722, 1723, 1729, 1726, 
-    1746, 1709, 1735, 1734, 1736, 1739, 1733, 1737, 1744, 1609, 1610, 1620, 
-    1575, 1610, 1620, 1749, 1610, 1620, 1608, 1610, 1620, 1735, 1610, 1620, 
-    1734, 1610, 1620, 1736, 1610, 1620, 1744, 1610, 1620, 1609, 1740, 1610, 
-    1620, 1580, 1610, 1620, 1581, 1610, 1620, 1605, 1610, 1620, 1610, 1576, 
-    1580, 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, 1610, 1578, 
-    1580, 1578, 1581, 1578, 1582, 1578, 1605, 1578, 1609, 1578, 1610, 1579, 
-    1580, 1579, 1605, 1579, 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581, 
-    1580, 1581, 1605, 1582, 1580, 1582, 1581, 1582, 1605, 1587, 1580, 1587, 
-    1581, 1587, 1582, 1587, 1605, 1589, 1581, 1589, 1605, 1590, 1580, 1590, 
-    1581, 1590, 1582, 1590, 1605, 1591, 1581, 1591, 1605, 1592, 1605, 1593, 
-    1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, 1581, 1601, 
-    1582, 1601, 1605, 1601, 1609, 1601, 1610, 1602, 1581, 1602, 1605, 1602, 
-    1609, 1602, 1610, 1603, 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 
-    1604, 1603, 1605, 1603, 1609, 1603, 1610, 1604, 1580, 1604, 1581, 1604, 
-    1582, 1604, 1605, 1604, 1609, 1604, 1610, 1605, 1580, 1605, 1581, 1605, 
-    1582, 1605, 1605, 1605, 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606, 
-    1582, 1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, 1605, 1607, 
-    1609, 1607, 1610, 1610, 1580, 1610, 1581, 1610, 1582, 1610, 1605, 1610, 
-    1609, 1610, 1610, 1584, 1648, 1585, 1648, 1609, 1648, 32, 1612, 1617, 
-    32, 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32, 1616, 1617, 32, 
-    1617, 1648, 1610, 1620, 1585, 1610, 1620, 1586, 1610, 1620, 1606, 1576, 
-    1585, 1576, 1586, 1576, 1606, 1578, 1585, 1578, 1586, 1578, 1606, 1579, 
-    1585, 1579, 1586, 1579, 1606, 1605, 1575, 1606, 1585, 1606, 1586, 1606, 
-    1606, 1610, 1585, 1610, 1586, 1610, 1606, 1610, 1620, 1582, 1610, 1620, 
-    1607, 1576, 1607, 1578, 1607, 1589, 1582, 1604, 1607, 1606, 1607, 1607, 
-    1648, 1610, 1607, 1579, 1607, 1587, 1607, 1588, 1605, 1588, 1607, 1600, 
-    1614, 1617, 1600, 1615, 1617, 1600, 1616, 1617, 1591, 1609, 1591, 1610, 
-    1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609, 1587, 1610, 
-    1588, 1609, 1588, 1610, 1581, 1609, 1581, 1610, 1580, 1609, 1580, 1610, 
-    1582, 1609, 1582, 1610, 1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610, 
-    1588, 1580, 1588, 1581, 1588, 1582, 1588, 1585, 1587, 1585, 1589, 1585, 
-    1590, 1585, 1575, 1611, 1578, 1580, 1605, 1578, 1581, 1580, 1578, 1581, 
-    1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605, 1581, 1578, 1605, 
-    1582, 1580, 1605, 1581, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581, 
-    1580, 1587, 1580, 1581, 1587, 1580, 1609, 1587, 1605, 1581, 1587, 1605, 
-    1580, 1587, 1605, 1605, 1589, 1581, 1581, 1589, 1605, 1605, 1588, 1581, 
-    1605, 1588, 1580, 1610, 1588, 1605, 1582, 1588, 1605, 1605, 1590, 1581, 
-    1609, 1590, 1582, 1605, 1591, 1605, 1581, 1591, 1605, 1605, 1591, 1605, 
-    1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605, 1609, 1594, 1605, 
-    1605, 1594, 1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1602, 1605, 
-    1581, 1602, 1605, 1605, 1604, 1581, 1605, 1604, 1581, 1610, 1604, 1581, 
-    1609, 1604, 1580, 1580, 1604, 1582, 1605, 1604, 1605, 1581, 1605, 1581, 
-    1580, 1605, 1581, 1605, 1605, 1581, 1610, 1605, 1580, 1581, 1605, 1580, 
-    1605, 1605, 1582, 1580, 1605, 1582, 1605, 1605, 1580, 1582, 1607, 1605, 
-    1580, 1607, 1605, 1605, 1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580, 
-    1605, 1606, 1580, 1609, 1606, 1605, 1610, 1606, 1605, 1609, 1610, 1605, 
-    1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578, 1580, 1609, 1578, 1582, 
-    1610, 1578, 1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609, 1580, 1605, 
-    1610, 1580, 1581, 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581, 
-    1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, 1604, 1605, 
-    1610, 1610, 1581, 1610, 1610, 1580, 1610, 1610, 1605, 1610, 1605, 1605, 
-    1610, 1602, 1605, 1610, 1606, 1581, 1610, 1593, 1605, 1610, 1603, 1605, 
-    1610, 1606, 1580, 1581, 1605, 1582, 1610, 1604, 1580, 1605, 1603, 1605, 
-    1605, 1580, 1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601, 1605, 
-    1610, 1576, 1581, 1610, 1587, 1582, 1610, 1606, 1580, 1610, 1589, 1604, 
-    1746, 1602, 1604, 1746, 1575, 1604, 1604, 1607, 1575, 1603, 1576, 1585, 
-    1605, 1581, 1605, 1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604, 
-    1593, 1604, 1610, 1607, 1608, 1587, 1604, 1605, 1589, 1604, 1609, 1589, 
-    1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 
-    32, 1608, 1587, 1604, 1605, 1580, 1604, 32, 1580, 1604, 1575, 1604, 
-    1607, 1585, 1740, 1575, 1604, 8212, 8211, 95, 123, 125, 12308, 12309, 
-    12304, 12305, 12298, 12299, 12300, 12301, 12302, 12303, 44, 12289, 
-    58, 63, 33, 35, 38, 42, 45, 60, 62, 92, 36, 37, 64, 32, 1611, 1600, 
-    1611, 32, 1612, 32, 1613, 32, 1614, 1600, 1614, 32, 1615, 1600, 1615, 
-    32, 1616, 1600, 1616, 32, 1617, 1600, 1617, 32, 1618, 1600, 1618, 1569, 
-    1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 
-    1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1601, 1602, 1603, 1604, 
-    1605, 1606, 1607, 1608, 1610, 1604, 1575, 1619, 1604, 1575, 1620, 1604, 
-    1575, 1621, 1604, 1575, 34, 39, 47, 91, 93, 94, 124, 126, 10629, 10630, 
-    12290, 12539, 12449, 12451, 12453, 12455, 12457, 12515, 12517, 12519, 
-    12483, 12540, 12531, 12441, 12442, 162, 163, 172, 166, 165, 8361, 9474, 
-    8592, 8593, 8594, 8595, 9632, 9675, 119127, 119141, 119128, 119141, 
-    119128, 119141, 119150, 119128, 119141, 119151, 119128, 119141, 119152, 
-    119128, 119141, 119153, 119128, 119141, 119154, 119225, 119141, 119226, 
-    119141, 119225, 119141, 119150, 119226, 119141, 119150, 119225, 119141, 
-    119151, 119226, 119141, 119151, 913, 914, 916, 917, 918, 919, 921, 
-    922, 923, 924, 925, 926, 927, 929, 931, 932, 934, 935, 936, 8711, 945, 
-    948, 950, 951, 955, 957, 958, 959, 963, 964, 965, 967, 968, 969, 8706, 
-    20029, 20024, 20033, 131362, 20320, 20411, 20482, 20602, 20633, 20687, 
-    13470, 132666, 20820, 20836, 20855, 132380, 13497, 20839, 20877, 132427, 
-    20887, 20900, 20172, 20908, 20917, 168415, 20995, 13535, 21051, 21062, 
-    21106, 21111, 13589, 21191, 21242, 21253, 21254, 21321, 21338, 21363, 
-    21373, 21375, 133676, 28784, 21450, 21471, 133987, 21483, 21489, 21510, 
-    21662, 21560, 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892, 
-    21913, 21931, 21939, 21954, 22294, 22295, 22097, 22132, 22766, 22478, 
-    22516, 22541, 22411, 22578, 22577, 22700, 136420, 22770, 22775, 22790, 
-    22810, 22818, 22882, 136872, 136938, 23020, 23067, 23079, 23000, 23142, 
-    14062, 136042, 23304, 23358, 137672, 23491, 23512, 23539, 138008, 23551, 
-    23558, 24371, 14209, 23648, 23744, 23693, 138724, 23875, 138726, 23918, 
-    23915, 23932, 24033, 24034, 14383, 24061, 24104, 24125, 24169, 14434, 
-    139651, 14460, 24240, 24243, 24246, 172946, 140081, 33281, 24354, 14535, 
-    144056, 156122, 24418, 24427, 14563, 24474, 24525, 24535, 24569, 24705, 
-    14650, 14620, 141012, 24775, 24904, 24908, 24910, 24954, 25010, 24996, 
-    25007, 25054, 25104, 25115, 25181, 25265, 25300, 25424, 142092, 25405, 
-    25340, 25448, 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705, 
-    25726, 25757, 25719, 14956, 25964, 143370, 26083, 26360, 26185, 15129, 
-    15112, 15076, 20882, 20885, 26368, 26268, 32941, 17369, 26395, 26401, 
-    26462, 26451, 144323, 15177, 26618, 26501, 26706, 144493, 26766, 26655, 
-    26900, 15261, 26946, 27043, 27114, 27304, 145059, 27355, 15384, 27425, 
-    145575, 27476, 15438, 27506, 27551, 27579, 146061, 138507, 146170, 
-    27726, 146620, 27839, 27853, 27751, 27926, 27966, 28009, 28024, 28037, 
-    146718, 27956, 28207, 28270, 15667, 28363, 28359, 147153, 28153, 28526, 
-    147294, 147342, 28614, 28729, 28702, 28699, 15766, 28746, 28797, 28791, 
-    28845, 132389, 28997, 148067, 29084, 17323, 29224, 29237, 29264, 149000, 
-    29312, 29333, 149301, 149524, 29562, 29579, 16044, 29605, 16056, 29767, 
-    29788, 29809, 29829, 29898, 16155, 29988, 150582, 30014, 150674, 139679, 
-    30224, 151457, 151480, 151620, 16380, 16392, 30452, 151795, 151794, 
-    151833, 151859, 30494, 30495, 30538, 16441, 30603, 16454, 16534, 152605, 
-    30798, 30924, 16611, 153126, 153242, 153285, 31211, 16687, 31306, 31311, 
-    153980, 154279, 31406, 16898, 154539, 31686, 31689, 16935, 154752, 
-    31954, 17056, 31976, 31971, 32000, 155526, 32099, 17153, 32199, 32258, 
-    32325, 17204, 156200, 156231, 17241, 156377, 32634, 156478, 32661, 
-    32762, 156890, 156963, 32864, 157096, 32880, 144223, 17365, 32946, 
-    33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284, 33284, 
-    36766, 17515, 33425, 33419, 33437, 21171, 33457, 33459, 33469, 33510, 
-    158524, 33565, 33635, 33709, 33571, 33725, 33767, 33619, 33738, 33740, 
-    33756, 158774, 159083, 158933, 17707, 34033, 34035, 34070, 160714, 
-    34148, 159532, 17757, 17761, 159665, 159954, 17771, 34384, 34407, 34409, 
-    34473, 34440, 34574, 34530, 34681, 34600, 34667, 34694, 19799, 34785, 
-    34817, 17913, 34912, 161383, 35031, 35038, 17973, 35066, 13499, 161966, 
-    162150, 18110, 18119, 35488, 35565, 35722, 162984, 36011, 36033, 36123, 
-    36215, 163631, 133124, 36299, 36284, 36336, 133342, 36564, 36664, 165330, 
-    165357, 37012, 37105, 37137, 165678, 37147, 37432, 37591, 37592, 37500, 
-    37881, 37909, 166906, 38283, 18837, 38327, 167287, 18918, 38595, 23986, 
-    38691, 168261, 168474, 19054, 19062, 38880, 168970, 19122, 169110, 
-    38923, 38953, 169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406, 
-    170800, 39698, 40000, 40189, 19662, 19693, 40295, 172238, 19704, 172293, 
-    172558, 172689, 19798, 40702, 40709, 40719, 40726, 173568
-};
-
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharDecompInfo(ch) (decompGroupMap[(decompPageMap[(((int)(ch)) & 0x1fffff) >> DECOMP_OFFSET_BITS] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))])
-
-#define GetDecompShift(info) ((info) & 0xffff)
-#define GetDecompLen(info) ((info) >> 16)
-
-
-#define COMP_OFFSET_BITS 8
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char compPageMap[] = {
-    0, 1, 2, 3, 4, 5, 6, 5, 5, 7, 5, 8, 9, 10, 5, 5, 11, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 12, 13, 5, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5
-};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static int compGroupMap[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 65564, 65640, 65738, -1, -1, 30, 
-    91, 141, 65, 121, 65701, 38, 94, 1, 65604, 124, 44, 100, 12, 76, 77, 
-    -1, 48, 105, 17, 84, 136, 54, 113, 23, 24, -1, -1, -1, -1, -1, -1, 
-    140, 64, 120, 71, 123, 65573, 99, 10, 75, 129, 47, 104, 16, 15, 83, 
-    135, -1, 110, 22, 86, 137, 59, 117, 118, 28, 89, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, 
-    65713, 65575, 101, 65550, -1, -1, 42, -1, -1, -1, -1, 65576, -1, -1, 
-    -1, -1, 130, 50, 65678, -1, 65628, -1, -1, -1, 115, -1, -1, -1, -1, 
-    -1, 32, -1, 65742, 65600, 67, 65704, -1, -1, 5, -1, -1, -1, -1, 65549, 
-    -1, -1, -1, -1, 107, 20, 65626, -1, 65587, -1, -1, -1, 87, -1, -1, 
-    -1, -1, -1, 142, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 106, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, 93, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 65624, 65722, -1, -1, -1, -1, 65632, 65730, 
-    -1, -1, -1, -1, -1, -1, 65597, 65699, 65567, 65649, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65728, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, 131, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, 33, -1, -1, 
-    -1, -1, -1, -1, 65546, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 65593, 65696, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65675, 
-    65554, 65625, 65724, -1, -1, -1, -1, 65731, 65590, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 65729, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 131073, 131074, 131075, 131077, 131079, -1, 131080, 131082, 131083, 
-    131084, 131098, 131102, 131085, -1, -1, 131086, -1, 131087, -1, 131076, 
-    131078, -1, -1, -1, -1, -1, -1, 131103, -1, -1, -1, -1, -1, -1, -1, 
-    131088, 131104, 131101, 131097, 131092, 131089, -1, -1, -1, -1, 131094, 
-    131093, -1, 131090, 131095, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 131091, -1, -1, 131072, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 34, -1, -1, -1, 122, -1, 96, -1, 8, -1, -1, -1, -1, -1, 80, 
-    -1, 65586, -1, -1, -1, 85, -1, -1, -1, 26, -1, -1, 65539, -1, 65707, 
-    -1, -1, 2, -1, -1, -1, 95, -1, 7, -1, 125, -1, -1, -1, -1, -1, 51, 
-    -1, 111, -1, -1, -1, 56, -1, -1, -1, 0, 138, 62, -1, -1, 65664, -1, 
-    -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 65736, -1, -1, -1, -1, -1, -1, -1, -1, -1, 97, -1, -1, 
-    65714, -1, 103, 14, 65622, 132, -1, 65581, -1, -1, -1, 65727, -1, -1, 
-    -1, -1, 139, -1, -1, -1, 65566, -1, -1, -1, 65706, -1, 65663, -1, -1, 
-    72, -1, -1, 65670, -1, 79, 133, 65582, 52, -1, 65556, -1, -1, -1, 65687, 
-    -1, -1, -1, -1, 63, -1, -1, -1, 65744, -1, -1, -1, 65659, -1, 65595, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 65658, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 65661, 65545, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 65651, 65542, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 65682, 65559, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    65733, -1, 65657, -1, -1, -1, -1, -1, -1, -1, -1, 196618, 131108, 196619, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 65618, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 65612, -1, -1, 65611, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 65734, -1, -1, -1, -1, -1, -1, -1, 
-    65656, -1, -1, 65655, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 196611, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196612, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    196613, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 196614, 196615, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 65577, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131105, -1, -1, 
-    -1, -1, -1, -1, -1, 98, 65584, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 131106, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65578, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 65716, -1, -1, 196616, -1, -1, -1, 127, -1, -1, -1, 65630, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, 131107, 196617, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131096, -1, 
-    -1, -1, -1, -1, -1, -1, 19, 65695, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 196610, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 131081, -1, -1, -1, -1, 196608, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 3, -1, -1, 65538, -1, -1, 196609, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65616, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65679, 
-    65557, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, 65685, 65561, -1, -1, -1, -1, -1, -1, 65743, 65601, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 114, 25, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65673, 65553, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 65540, 65605, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 82, 134, 65591, 65692, 65693, 65565, 65641, 65739, 58, 
-    116, 65568, 65652, 65543, 65609, 65610, 65710, 36, 92, -1, -1, -1, 
-    -1, -1, -1, 9, 73, -1, -1, -1, -1, -1, -1, 53, 108, 65690, 65563, 65639, 
-    65737, 65598, 65700, 27, 88, 65541, 65606, 65607, 65709, 65572, 65667, 
-    11, 69, -1, -1, -1, -1, -1, -1, 126, 45, -1, -1, -1, -1, -1, -1, 13, 
-    78, -1, -1, -1, -1, -1, -1, 55, 112, -1, -1, -1, -1, -1, -1, 29, 90, 
-    -1, -1, -1, -1, -1, -1, -1, 70, -1, -1, -1, -1, -1, -1, 128, 46, 65683, 
-    65560, 65635, 65732, 65592, 65694, 109, 21, 65642, 65740, 65599, 65702, 
-    65569, 65653, 65544, -1, -1, -1, 65574, -1, -1, -1, -1, -1, -1, -1, 
-    65552, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, 65537, -1, -1, -1, -1, -1, -1, -1, 
-    -1, 40, -1, -1, -1, -1, -1, -1, 65680, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 65570, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 65705, -1, 65660, -1, 65614, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 65698, -1, 65644, -1, 65741, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 65711, -1, -1, -1, -1, 65619, -1, -1, 65676, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, 65668, -1, 65548, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65648, 
-    -1, -1, -1, -1, -1, -1, 65547, -1, 65715, -1, -1, 65551, -1, -1, -1, 
-    -1, 65681, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 65596, -1, -1, 65647, 65536, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, 65721, 65583, -1, -1, 65558, 65631, -1, 
-    -1, 65688, 65562, 65637, 65735, -1, -1, -1, -1, 65646, 65745, -1, -1, 
-    65571, 65662, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65580, 65579, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65602, -1, 
-    -1, -1, -1, -1, 65613, 65712, -1, 65669, -1, -1, -1, -1, -1, -1, 65555, 
-    65629, 65725, 65588, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65718, -1, -1, 
-    -1, -1, 65708, -1, 65703, -1, 65697, -1, 65686, -1, 65684, -1, 65677, 
-    -1, 65671, -1, 65665, -1, 65650, -1, 65645, -1, 65638, -1, 65633, -1, 
-    -1, 65623, -1, 65620, -1, 65615, -1, -1, -1, -1, -1, -1, 60, -1, -1, 
-    74, -1, -1, 68, -1, -1, 61, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, -1, -1, 131099, 131100, -1, -1, 65717, -1, -1, -1, -1, 
-    -1, -1, -1, -1, 65691, -1, -1, -1, -1, 65674, -1, 65672, -1, 65666, 
-    -1, 65654, -1, 65643, -1, 65636, -1, 65634, -1, 65627, -1, 65621, -1, 
-    65617, -1, 65608, -1, 65603, -1, -1, 65594, -1, 65589, -1, 65585, -1, 
-    -1, -1, -1, -1, -1, 41, -1, -1, 31, -1, -1, 49, -1, -1, 43, -1, -1, 
-    35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 65726, 65723, 65720, 65719, -1, -1, -1, -1, -1, -1, -1, 
-    -1, -1, -1, 65689, -1, -1
-};
-
-/*
- * Lists of compositions for characters that appears only in one composition
- */
-
-static int compFirstList[][2] = {
-    {824, 8817}, {837, 8119}, {3530, 3549}, {837, 8116}, {770, 7896}, 
-    {837, 8090}, {776, 1243}, {837, 8076}, {837, 8114}, {783, 1143}, 
-    {780, 494}, {824, 8772}, {824, 8742}, {769, 7727}, {769, 7688}, 
-    {824, 8777}, {837, 8178}, {770, 7879}, {772, 481}, {824, 8938}, 
-    {769, 1116}, {772, 7737}, {824, 8824}, {776, 1259}, {837, 8099}, 
-    {772, 7773}, {824, 8833}, {837, 8083}, {824, 8814}, {837, 8069}, 
-    {776, 1268}, {776, 7802}, {837, 8074}, {837, 8110}, {837, 8183}, 
-    {824, 8840}, {837, 8094}, {775, 7711}, {837, 8130}, {769, 506}, 
-    {769, 7726}, {3031, 2964}, {3158, 3144}, {824, 8931}, {824, 8930}, 
-    {769, 1036}, {776, 1247}, {824, 8821}, {3006, 3019}, {12441, 12489}, 
-    {788, 8172}, {769, 511}, {824, 8941}, {12441, 12487}, {772, 561}, 
-    {837, 8066}, {837, 8102}, {772, 492}, {12441, 12485}, {776, 1261}, 
-    {824, 8802}, {769, 7800}, {837, 8086}, {837, 8108}, {769, 507}, 
-    {775, 7785}, {824, 8876}, {12441, 12482}, {770, 308}, {770, 7897}, 
-    {837, 8091}, {837, 8092}, {12441, 12480}, {837, 8077}, {837, 8078}, 
-    {1620, 1728}, {1620, 1747}, {824, 8877}, {824, 8622}, {12441, 12393}, 
-    {4142, 4134}, {12441, 12478}, {1620, 1730}, {824, 8713}, 
-    {12441, 12391}, {12441, 12476}, {776, 1246}, {12441, 12389}, 
-    {775, 7780}, {774, 7708}, {772, 555}, {12441, 12474}, {769, 510}, 
-    {824, 8939}, {3285, 3275}, {824, 8825}, {775, 7782}, {12441, 12386}, 
-    {12441, 12472}, {837, 8100}, {12441, 12470}, {824, 8928}, 
-    {12441, 12384}, {837, 8084}, {824, 8800}, {837, 8070}, {837, 8106}, 
-    {12441, 12468}, {824, 8655}, {12441, 12382}, {824, 8836}, 
-    {824, 8816}, {824, 8769}, {776, 7803}, {12441, 12380}, {776, 1242}, 
-    {837, 8075}, {837, 8111}, {12441, 12466}, {2364, 2356}, {2364, 2353}, 
-    {1620, 1574}, {776, 1111}, {776, 1273}, {824, 8603}, {783, 1142}, 
-    {824, 8841}, {776, 1260}, {837, 8180}, {12441, 12378}, {12441, 12464}, 
-    {837, 8095}, {824, 8740}, {824, 8879}, {769, 1107}, {12441, 12376}, 
-    {12441, 12462}, {770, 7878}, {12441, 12460}, {772, 480}, 
-    {824, 8716}, {12441, 12374}, {772, 554}, {772, 7736}, {837, 8135}, 
-    {824, 8813}, {776, 1258}, {837, 8098}, {12441, 12372}, {772, 7772}, 
-    {12441, 12370}, {776, 1255}, {824, 8832}, {12441, 12542}, 
-    {837, 8082}, {12441, 12532}, {837, 8067}, {837, 8068}, {837, 8103}, 
-    {3390, 3403}, {772, 493}, {12441, 12368}, {824, 8653}, {769, 7801}, 
-    {837, 8087}, {775, 7710}, {837, 8109}, {12441, 12366}, {769, 7689}, 
-    {824, 8602}, {776, 1272}, {837, 8132}, {12441, 12364}, {837, 8093}, 
-    {837, 8079}, {824, 8708}, {824, 8878}, {772, 478}, {769, 1027}, 
-    {824, 8775}, {3285, 3264}, {12441, 12446}, {12441, 12436}, 
-    {12441, 12538}, {12441, 12537}, {824, 8820}, {775, 7781}, 
-    {12441, 12536}, {774, 7709}, {824, 8940}, {12441, 12535}, 
-    {776, 1254}, {775, 7835}, {780, 495}, {775, 7783}, {772, 560}, 
-    {837, 8101}, {1620, 1572}, {2364, 2345}, {824, 8929}, {776, 1031}, 
-    {837, 8085}, {824, 8815}, {837, 8071}, {837, 8107}, {824, 8654}, 
-    {772, 479}, {775, 7784}, {776, 1269}, {824, 8837}
-};
-
-static int compSecondList[][2] = {
-    {3545, 3548}, {3545, 3550}, {3398, 3404}, {2503, 2507}, {2503, 2508}, 
-    {2887, 2891}, {2887, 2888}, {2887, 2892}, {3270, 3274}, {3270, 3272}, 
-    {1575, 1570}, {1575, 1573}
-};
-
-/*
- * Compositions matrix
- */
-
-static int compBothList[144][37] = {
-    {
-        8179, 8060, 974, 0, 8032, 0, 8033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 8182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 204, 205, 206, 0, 296, 0, 298, 300, 0, 304, 207, 7880, 463, 
-        520, 522, 7882, 302, 7724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0
-    },
-    {
-        8115, 8048, 940, 0, 7936, 0, 7937, 8113, 8112, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 8118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 3546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8157, 8158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        8159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7873, 7871, 0, 0, 7877, 0, 0, 0, 0, 0, 0, 7875, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7846, 7844, 0, 0, 7850, 0, 0, 0, 0, 0, 0, 7848, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8131, 8052, 942, 0, 7968, 0, 7969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 8134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8154, 906, 0, 7992, 0, 7993, 8153, 8152, 0, 0, 938, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0
-    },
-    {
-        0, 7962, 7964, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 7715, 7719, 0, 543, 0, 0, 7717, 
-        0, 0, 0, 7721, 7723, 0, 7830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0
-    },
-    {
-        0, 7986, 7988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        7990, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 504, 323, 0, 0, 209, 0, 0, 0, 0, 7748, 0, 0, 327, 0, 0, 7750, 
-        0, 0, 0, 325, 0, 7754, 7752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0
-    },
-    {
-        0, 8002, 8004, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 1217, 0, 0, 1244, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 505, 324, 0, 0, 241, 0, 0, 0, 0, 7749, 0, 0, 328, 0, 0, 7751, 
-        0, 0, 0, 326, 0, 7755, 7753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0
-    },
-    {
-        0, 0, 7743, 0, 0, 0, 0, 0, 0, 0, 7745, 0, 0, 0, 0, 0, 7747, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7786, 0, 0, 356, 0, 0, 7788, 0, 0, 
-        0, 354, 0, 7792, 7790, 0, 538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7701, 7703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 3402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 7757, 0, 0, 0, 0, 557, 0, 0, 0, 7759, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8105, 8043, 8045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 8047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 347, 349, 0, 0, 0, 0, 0, 0, 7777, 0, 0, 353, 0, 0, 7779, 
-        0, 0, 0, 351, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7922, 221, 374, 0, 7928, 0, 562, 0, 0, 7822, 376, 7926, 0, 0, 
-        0, 7924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0
-    },
-    {
-        0, 0, 377, 7824, 0, 0, 0, 0, 0, 0, 379, 0, 0, 381, 0, 0, 7826, 
-        0, 0, 0, 0, 0, 0, 7828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 7853, 0, 0, 0, 0, 7863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8188, 8186, 911, 0, 8040, 0, 8041, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8088, 7978, 7980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7923, 253, 375, 0, 7929, 0, 563, 0, 0, 7823, 255, 7927, 0, 0, 
-        0, 7925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7833, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0
-    },
-    {
-        0, 8018, 8020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        8022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 192, 193, 194, 0, 195, 0, 256, 258, 0, 550, 196, 7842, 461, 
-        512, 514, 7840, 260, 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 7680, 0, 
-        0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12499, 12500, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7847, 7845, 0, 0, 7851, 0, 0, 0, 0, 0, 0, 7849, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7915, 7913, 0, 0, 7919, 0, 0, 0, 0, 0, 0, 7917, 0, 0, 0, 7921, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8124, 8122, 902, 0, 7944, 0, 7945, 8121, 8120, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12508, 12509, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7954, 7956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7760, 7762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 500, 284, 0, 0, 0, 7712, 286, 0, 288, 0, 0, 486, 0, 0, 0, 
-        0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 979, 0, 0, 0, 0, 0, 0, 0, 0, 980, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8141, 8142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        8143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12496, 12497, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7872, 7870, 0, 0, 7876, 0, 0, 0, 0, 0, 0, 7874, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12505, 12506, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, 7734, 0, 0, 
-        0, 315, 0, 7740, 7738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7995, 7997, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        7999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8097, 8035, 8037, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 8039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 7729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 489, 0, 0, 7731, 0, 0, 
-        0, 311, 0, 0, 7733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 340, 0, 0, 0, 0, 0, 0, 0, 7768, 0, 0, 344, 528, 530, 7770, 
-        0, 0, 0, 342, 0, 0, 7774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12502, 12503, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 7756, 0, 0, 0, 0, 556, 0, 0, 0, 7758, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8056, 972, 0, 8000, 0, 8001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 1117, 0, 0, 0, 0, 0, 1251, 1081, 0, 0, 1253, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8080, 7970, 7972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7808, 7810, 372, 0, 0, 0, 0, 0, 0, 7814, 7812, 0, 0, 0, 0, 7816, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8010, 8012, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8058, 973, 0, 8016, 0, 8017, 8161, 8160, 0, 0, 971, 0, 0, 0, 
-        0, 0, 0, 0, 8166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12412, 12413, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8072, 7946, 7948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7950, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 7805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7807, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12400, 12401, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12409, 12410, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8162, 944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8167, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 1263, 1118, 0, 0, 1265, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1267, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7683, 0, 0, 0, 0, 0, 7685, 0, 0, 
-        0, 0, 0, 0, 7687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7690, 0, 0, 270, 0, 0, 7692, 0, 0, 
-        0, 7696, 0, 7698, 7694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7857, 7855, 0, 0, 7861, 0, 0, 0, 0, 0, 0, 7859, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 509, 0, 0, 0, 0, 483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12406, 12407, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7987, 7989, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        7991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8027, 8029, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        8031, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7691, 0, 0, 271, 0, 0, 7693, 0, 0, 
-        0, 7697, 0, 7699, 7695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 1233, 0, 0, 1235, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7963, 7965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 12403, 12404, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 236, 237, 238, 0, 297, 0, 299, 301, 0, 0, 239, 7881, 464, 521, 
-        523, 7883, 303, 7725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0
-    },
-    {
-        0, 210, 211, 212, 0, 213, 0, 332, 334, 0, 558, 214, 7886, 465, 
-        524, 526, 7884, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336, 416, 
-        0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 7764, 0, 0, 0, 0, 0, 0, 0, 7766, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8003, 8005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 1104, 0, 0, 0, 0, 0, 0, 1239, 0, 0, 1105, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8184, 908, 0, 8008, 0, 8009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7900, 7898, 0, 0, 7904, 0, 0, 0, 0, 0, 0, 7902, 0, 0, 0, 7906, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8064, 7938, 7940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 242, 243, 244, 0, 245, 0, 333, 335, 0, 559, 246, 7887, 466, 
-        525, 527, 7885, 491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 337, 417, 
-        0, 0, 0, 0, 0
-    },
-    {
-        0, 217, 218, 219, 0, 360, 0, 362, 364, 0, 0, 220, 7910, 467, 532, 
-        534, 7908, 370, 7796, 0, 0, 0, 7798, 0, 0, 0, 366, 0, 0, 0, 368, 
-        431, 7794, 0, 0, 0, 0
-    },
-    {
-        0, 8170, 910, 0, 0, 0, 8025, 8169, 8168, 0, 0, 939, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7787, 7831, 0, 357, 0, 0, 7789, 0, 
-        0, 0, 355, 0, 7793, 7791, 0, 539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0
-    },
-    {
-        0, 476, 472, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8089, 7979, 7981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7983, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 378, 7825, 0, 0, 0, 0, 0, 0, 380, 0, 0, 382, 0, 0, 7827, 
-        0, 0, 0, 0, 0, 0, 7829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8019, 8021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        8023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7682, 0, 0, 0, 0, 0, 7684, 0, 0, 
-        0, 0, 0, 0, 7686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7955, 7957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7761, 7763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 292, 0, 0, 0, 0, 0, 0, 7714, 7718, 0, 542, 0, 0, 7716, 
-        0, 0, 0, 7720, 7722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0
-    },
-    {
-        0, 8050, 941, 0, 7952, 0, 7953, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8140, 8138, 905, 0, 7976, 0, 7977, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 1232, 0, 0, 1234, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3018, 3020, 0, 0
-    },
-    {
-        0, 0, 501, 285, 0, 0, 0, 7713, 287, 0, 289, 0, 0, 487, 0, 0, 0, 
-        0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 7742, 0, 0, 0, 0, 0, 0, 0, 7744, 0, 0, 0, 0, 0, 7746, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 508, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8173, 901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8129, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 1024, 0, 0, 0, 0, 0, 0, 1238, 0, 0, 1025, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 7735, 0, 0, 
-        0, 316, 0, 7741, 7739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 346, 348, 0, 0, 0, 0, 0, 0, 7776, 0, 0, 352, 0, 0, 7778, 
-        0, 0, 0, 350, 0, 0, 0, 0, 536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7700, 7702, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7891, 7889, 0, 0, 7895, 0, 0, 0, 0, 0, 0, 7893, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8081, 7971, 7973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8104, 8042, 8044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 8046, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 7769, 0, 0, 345, 529, 531, 7771, 
-        0, 0, 0, 343, 0, 0, 7775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-        
-    },
-    {
-        0, 0, 0, 0, 8164, 0, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8011, 8013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7818, 7820, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 7852, 0, 0, 0, 0, 7862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 475, 471, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8073, 7947, 7949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7809, 7811, 373, 0, 0, 0, 0, 0, 0, 7815, 7813, 0, 0, 0, 0, 7817, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 7832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7819, 7821, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7914, 7912, 0, 0, 7918, 0, 0, 0, 0, 0, 0, 7916, 0, 0, 0, 7920, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 263, 265, 0, 0, 0, 0, 0, 0, 267, 0, 0, 269, 0, 0, 0, 0, 0, 
-        0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 200, 201, 202, 0, 7868, 0, 274, 276, 0, 278, 203, 7866, 282, 
-        516, 518, 7864, 280, 7706, 0, 552, 0, 7704, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8136, 904, 0, 7960, 0, 7961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 232, 233, 234, 0, 7869, 0, 275, 277, 0, 279, 235, 7867, 283, 
-        517, 519, 7865, 281, 7707, 0, 553, 0, 7705, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 7728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 7730, 0, 0, 
-        0, 310, 0, 0, 7732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 8054, 943, 0, 7984, 0, 7985, 8145, 8144, 0, 0, 970, 0, 0, 0, 
-        0, 0, 0, 0, 8150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0
-    },
-    {
-        0, 7994, 7996, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        7998, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3271, 0
-    },
-    {
-        8096, 8034, 8036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 8038, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7890, 7888, 0, 0, 7894, 0, 0, 0, 0, 0, 0, 7892, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7901, 7899, 0, 0, 7905, 0, 0, 0, 0, 0, 0, 7903, 0, 0, 0, 7907, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 1037, 0, 0, 0, 0, 0, 1250, 1049, 0, 0, 1252, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 1218, 0, 0, 1245, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        8065, 7939, 7941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 7943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 7765, 0, 0, 0, 0, 0, 0, 0, 7767, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 7804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7806, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 249, 250, 251, 0, 361, 0, 363, 365, 0, 0, 252, 7911, 468, 533, 
-        535, 7909, 371, 7797, 0, 0, 0, 7799, 0, 0, 0, 367, 0, 0, 0, 369, 
-        432, 7795, 0, 0, 0, 0
-    },
-    {
-        0, 8146, 912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8151, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 1262, 1038, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1266, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 224, 225, 226, 0, 227, 0, 257, 259, 0, 551, 228, 7843, 462, 
-        513, 515, 7841, 261, 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, 7681, 0, 
-        0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 262, 264, 0, 0, 0, 0, 0, 0, 266, 0, 0, 268, 0, 0, 0, 0, 0, 
-        0, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 7856, 7854, 0, 0, 7860, 0, 0, 0, 0, 0, 0, 7858, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1571
-    },
-};
-
-
-#define GetUniCharCompInfo(ch) (compGroupMap[(compPageMap[(((int)(ch)) & 0x1fffff) >> COMP_OFFSET_BITS] << COMP_OFFSET_BITS) | ((ch) & ((1 << COMP_OFFSET_BITS)-1))])
-
-#define CompSingleMask (1 << 16)
-#define CompMask ((1 << 16) - 1)
-#define CompSecondMask (1 << 17)
-
diff --git a/src/stringprep/uni_parse.tcl b/src/stringprep/uni_parse.tcl
deleted file mode 100644 (file)
index 100631b..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-# uni_parse.tcl --
-#
-#      This program parses the UnicodeData file and generates the
-#      corresponding uni_data.c file with compressed character
-#      data tables.  The input to this program should be rfc3454.txt
-#
-# Copyright (c) 1998-1999 by Scriptics Corporation.
-# All rights reserved.
-#
-# Modified for ejabberd by Alexey Shchepin
-# 
-# RCS: @(#) $Id$
-
-
-namespace eval uni {
-    set shift 8;               # number of bits of data within a page
-                               # This value can be adjusted to find the
-                               # best split to minimize table size
-
-    variable pMap;             # map from page to page index, each entry is
-                               # an index into the pages table, indexed by
-                               # page number
-    variable pages;            # map from page index to page info, each
-                               # entry is a list of indices into the groups
-                               # table, the list is indexed by the offset
-    variable groups;           # list of character info values, indexed by
-                               # group number, initialized with the
-                               # unassigned character group
-}
-
-proc uni::getValue {i} {
-    variable casemap
-    variable casemap2
-    variable tablemap
-
-    if {[info exists tablemap($i)]} {
-       set tables $tablemap($i)
-    } else {
-       set tables {}
-    }
-
-    if {[info exists casemap2($i)]} {
-       set multicase 1
-       set delta $casemap2($i)
-    } else {
-       set multicase 0
-       if {[info exists casemap($i)]} {
-           set delta $casemap($i)
-       } else {
-           set delta 0
-       }
-    }
-
-    if {abs($delta) > 0xFFFFF} {
-       puts "delta must be less than 22 bits wide"
-       exit
-    }
-
-    set ac 0
-    set c11 0
-    set c21 0
-    set b1 0
-    set d1 0
-    set d2 0
-    set xnp 0
-
-    foreach tab $tables {
-       switch -glob -- $tab {
-           C.1.1 {set c11 1}
-           C.2.1 {set c21 1}
-           C.*   {set ac 1}
-           A.1   {set ac 1}
-           B.1   {set b1 1}
-           D.1   {set d1 1}
-           D.2   {set d2 1}
-           XNP   {set xnp 1}
-       }
-    }
-
-    set val [expr {($ac  << 0) |
-                  ($c11 << 1) |
-                  ($c21 << 2) |
-                  ($b1  << 3) |
-                  ($d1  << 4) |
-                  ($d2  << 5) |
-                  ($xnp << 6) |
-                  ($multicase << 7) |
-                  ($delta << 11)}]
-
-    return $val
-}
-
-proc uni::getGroup {value} {
-    variable groups
-
-    set gIndex [lsearch -exact $groups $value]
-    if {$gIndex == -1} {
-       set gIndex [llength $groups]
-       lappend groups $value
-    }
-    return $gIndex
-}
-
-proc uni::addPage {info} {
-    variable pMap
-    variable pages
-    variable pages_map
-    
-    if {[info exists pages_map($info)]} {
-       lappend pMap $pages_map($info)
-    } else {
-       set pIndex [llength $pages]
-       lappend pages $info
-       set pages_map($info) $pIndex
-       lappend pMap $pIndex
-    }
-    return
-}
-
-
-proc uni::load_tables {data} {
-    variable casemap
-    variable casemap2
-    variable multicasemap
-    variable tablemap
-
-    set multicasemap {}
-    set table ""
-
-    foreach line [split $data \n] {
-       if {$table == ""} {
-           if {[regexp {   ----- Start Table (.*) -----} $line temp table]} {
-               #puts "Start table '$table'"
-           }
-       } else {
-           if {[regexp {   ----- End Table (.*) -----} $line temp table1]} {
-               set table ""
-           } else {
-               if {$table == "B.1"} {
-                   if {[regexp {^   ([[:xdigit:]]+); ;} $line \
-                            temp val]} {
-                       scan $val %x val
-                       if {$val <= 0x10ffff} {
-                           lappend tablemap($val) $table
-                       }
-                   }
-               } elseif {$table == "B.2"} {
-                   if {[regexp {^   ([[:xdigit:]]+); ([[:xdigit:]]+);} $line \
-                            temp from to]} {
-                       scan $from %x from
-                       scan $to %x to
-                       if {$from <= 0x10ffff && $to <= 0x10ffff} {
-                           set casemap($from) [expr {$to - $from}]
-                       }
-                   } elseif {[regexp {^   ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
-                            temp from to1 to2]} {
-                       scan $from %x from
-                       scan $to1 %x to1
-                       scan $to2 %x to2
-                       if {$from <= 0x10ffff && \
-                               $to1 <= 0x10ffff && $to2 <= 0x10ffff} {
-                           set casemap2($from) [llength $multicasemap]
-                           lappend multicasemap [list $to1 $to2]
-                       }
-                   } elseif {[regexp {^   ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \
-                            temp from to1 to2 to3]} {
-                       scan $from %x from
-                       scan $to1 %x to1
-                       scan $to2 %x to2
-                       scan $to3 %x to3
-                       if {$from <= 0x10ffff && \
-                               $to1 <= 0x10ffff && $to2 <= 0x10ffff && \
-                               $to3 <= 0x10ffff} {
-                           set casemap2($from) [llength $multicasemap]
-                           lappend multicasemap [list $to1 $to2 $to3]
-                       }
-                   } else {
-                       #puts "missed: $line"
-                   }
-                   
-               } elseif {$table != "B.3"} {
-                   if {[regexp {^   ([[:xdigit:]]+)-([[:xdigit:]]+)} $line \
-                            temp from to]} {
-                       scan $from %x from
-                       scan $to %x to
-                       for {set i $from} {$i <= $to && $i <= 0x10ffff} {incr i} {
-                           lappend tablemap($i) $table
-                       }
-                   } elseif {[regexp {^   ([[:xdigit:]]+)} $line \
-                            temp val]} {
-                       scan $val %x val
-                       if {$val <= 0x10ffff} {
-                           lappend tablemap($val) $table
-                       }
-                   }
-               }
-           }
-       }
-    }
-
-    # XMPP nodeprep prohibited
-    foreach val {22 26 27 2f 3a 3c 3e 40} {
-       scan $val %x val
-       lappend tablemap($val) XNP
-    }
-}
-
-proc uni::buildTables {} {
-    variable shift
-
-    variable casemap
-    variable tablemap
-
-    variable pMap {}
-    variable pages {}
-    variable groups {}
-    set info {}                        ;# temporary page info
-    
-    set mask [expr {(1 << $shift) - 1}]
-
-    set next 0
-
-    for {set i 0} {$i <= 0x10ffff} {incr i} {
-       set gIndex [getGroup [getValue $i]]
-
-       # Split character index into offset and page number
-       set offset [expr {$i & $mask}]
-       set page [expr {($i >> $shift)}]
-
-       # Add the group index to the info for the current page
-       lappend info $gIndex
-
-       # If this is the last entry in the page, add the page
-       if {$offset == $mask} {
-           addPage $info
-           set info {}
-       }
-    }
-    return
-}
-
-proc uni::main {} {
-    global argc argv0 argv
-    variable pMap
-    variable pages
-    variable groups
-    variable shift
-    variable multicasemap
-
-    if {$argc != 2} {
-       puts stderr "\nusage: $argv0 <datafile> <outdir>\n"
-       exit 1
-    }
-    set f [open [lindex $argv 0] r]
-    set data [read $f]
-    close $f
-
-    load_tables $data
-    buildTables
-    puts "X = [llength $pMap]  Y= [llength $pages]  A= [llength $groups]"
-    set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
-    puts "shift = $shift, space = $size"
-
-    set f [open [file join [lindex $argv 1] uni_data.c] w]
-    fconfigure $f -translation lf
-    puts $f "/*
- * uni_data.c --
- *
- *     Declarations of Unicode character information tables.  This file is
- *     automatically generated by the uni_parse.tcl script.  Do not
- *     modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) \$Id\$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables.  The lower OFFSET_BITS comprise an offset
- * into a page of characters.  The upper bits comprise the page number.
- */
-
-#define OFFSET_BITS $shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char pageMap\[\] = {"
-    set line "    "
-    set last [expr {[llength $pMap] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       append line [lindex $pMap $i]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 70} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static unsigned short int groupMap\[\] = {"
-    set line "    "
-    set lasti [expr {[llength $pages] - 1}]
-    for {set i 0} {$i <= $lasti} {incr i} {
-       set page [lindex $pages $i]
-       set lastj [expr {[llength $page] - 1}]
-       for {set j 0} {$j <= $lastj} {incr j} {
-           append line [lindex $page $j]
-           if {$j != $lastj || $i != $lasti} {
-               append line ", "
-           }
-           if {[string length $line] > 70} {
-               puts $f $line
-               set line "    "
-           }
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * Each group represents a unique set of character attributes.  The attributes
- * are encoded into a 32-bit value as follows:
- *
- * Bit  0      A.1 | C.1.2 | C.2.2 | C.3 -- C.9
- *
- * Bit  1      C.1.1
- *
- * Bit  2      C.2.1
- *
- * Bit  3      B.1
- *
- * Bit  4      D.1
- *
- * Bit  5      D.2
- *
- * Bit  6      XNP
- *
- * Bit  7      Case maps to several characters
- *
- * Bits 8-10   Reserved for future use.
- *
- * Bits 11-31  Case delta: delta for case conversions.  This should be the
- *                         highest field so we can easily sign extend.
- */
-
-static int groups\[\] = {"
-    set line "    "
-    set last [expr {[llength $groups] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       set val [lindex $groups $i]
-
-       append line [format "%d" $val]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 65} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * Table for characters that lowercased to multiple ones
- */
-
-static int multiCaseTable\[\]\[4\] = {"
-    set last [expr {[llength $multicasemap] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       set val [lindex $multicasemap $i]
-
-       set line "    "
-       append line [format "{%d, %s}" [llength $val] [join $val ", "]]
-       if {$i != $last} {
-           append line ", "
-       }
-       puts $f $line
-    }
-    puts $f "};
-
-/*
- * The following constants are used to determine the category of a
- * Unicode character.
- */
-
-#define ACMask  (1 << 0)
-#define C11Mask (1 << 1)
-#define C21Mask (1 << 2)
-#define B1Mask  (1 << 3)
-#define D1Mask  (1 << 4)
-#define D2Mask  (1 << 5)
-#define XNPMask (1 << 6)
-#define MCMask  (1 << 7)
-
-/*
- * The following macros extract the fields of the character info.  The
- * GetDelta() macro is complicated because we can't rely on the C compiler
- * to do sign extension on right shifts.
- */
-
-#define GetCaseType(info) (((info) & 0xE0) >> 5)
-#define GetCategory(info) ((info) & 0x1F)
-#define GetDelta(info) (((info) > 0) ? ((info) >> 11) : (~(~((info)) >> 11)))
-#define GetMC(info) (multiCaseTable\[GetDelta(info)\])
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0x1fffff) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\])
-"
-
-    close $f
-}
-
-uni::main
-
-return
diff --git a/src/stringprep/uni_parse2.tcl b/src/stringprep/uni_parse2.tcl
deleted file mode 100644 (file)
index 950090a..0000000
+++ /dev/null
@@ -1,702 +0,0 @@
-# uni_parse2.tcl --
-#
-#      This program parses the UnicodeData file and generates the
-#      corresponding uni_norm.c file with compressed character
-#      data tables.  The input to this program should be
-#      UnicodeData-3.2.0.txt and CompositionExclusions-3.2.0.txt files from:
-#          ftp://ftp.unicode.org/Public/UNIDATA/
-#
-# Copyright (c) 1998-1999 by Scriptics Corporation.
-# All rights reserved.
-#
-# Modified for ejabberd by Alexey Shchepin
-# 
-# RCS: @(#) $Id$
-
-
-namespace eval uni {
-    set cclass_shift 8
-    set decomp_shift 8
-    set comp_shift 8
-    set shift 5;               # number of bits of data within a page
-                               # This value can be adjusted to find the
-                               # best split to minimize table size
-
-    variable pMap;             # map from page to page index, each entry is
-                               # an index into the pages table, indexed by
-                               # page number
-    variable pages;            # map from page index to page info, each
-                               # entry is a list of indices into the groups
-                               # table, the list is indexed by the offset
-    variable groups;           # list of character info values, indexed by
-                               # group number, initialized with the
-                               # unassigned character group
-
-    variable categories {
-       Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp
-       Cc Cf Co Cs Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So
-    };                         # Ordered list of character categories, must
-                               # match the enumeration in the header file.
-
-    variable titleCount 0;     # Count of the number of title case
-                               # characters.  This value is used in the
-                               # regular expression code to allocate enough
-                               # space for the title case variants.
-}
-
-proc uni::getValue {items index} {
-    variable categories
-    variable titleCount
-
-    # Extract character info
-
-    set category [lindex $items 2]
-    if {[scan [lindex $items 12] %4x toupper] == 1} {
-       set toupper [expr {$index - $toupper}]
-    } else {
-       set toupper {}
-    }
-    if {[scan [lindex $items 13] %4x tolower] == 1} {
-       set tolower [expr {$tolower - $index}]
-    } else {
-       set tolower {}
-    }
-    if {[scan [lindex $items 14] %4x totitle] == 1} {
-       set totitle [expr {$index - $totitle}]
-    } else {
-       set totitle {}
-    }
-
-    set categoryIndex [lsearch -exact $categories $category]
-    if {$categoryIndex < 0} {
-       puts "Unexpected character category: $index($category)"
-       set categoryIndex 0
-    } elseif {$category == "Lt"} {
-       incr titleCount
-    }
-
-    return "$categoryIndex,$toupper,$tolower,$totitle"
-}
-
-proc uni::getGroup {value} {
-    variable groups
-
-    set gIndex [lsearch -exact $groups $value]
-    if {$gIndex == -1} {
-       set gIndex [llength $groups]
-       lappend groups $value
-    }
-    return $gIndex
-}
-
-proc uni::addPage {info} {
-    variable pMap
-    variable pages
-    
-    set pIndex [lsearch -exact $pages $info]
-    if {$pIndex == -1} {
-       set pIndex [llength $pages]
-       lappend pages $info
-    }
-    lappend pMap $pIndex
-    return
-}
-
-proc uni::addPage {map_var pages_var info} {
-    variable $map_var
-    variable $pages_var
-    
-    set pIndex [lsearch -exact [set $pages_var] $info]
-    if {$pIndex == -1} {
-       set pIndex [llength [set $pages_var]]
-       lappend $pages_var $info
-    }
-    lappend $map_var $pIndex
-    return
-}
-
-proc uni::load_exclusions {data} {
-    variable exclusions
-
-    foreach line [split $data \n] {
-       if {$line == ""} continue
-
-       set items [split $line " "]
-
-       if {[lindex $items 0] == "#"} continue
-
-       scan [lindex $items 0] %x index
-
-       set exclusions($index) ""
-    }
-}
-
-proc uni::load_tables {data} {
-    variable cclass_map
-    variable decomp_map
-    variable comp_map
-    variable comp_first
-    variable comp_second
-    variable exclusions
-
-    foreach line [split $data \n] {
-       if {$line == ""} continue
-
-       set items [split $line \;]
-
-       scan [lindex $items 0] %x index
-       set cclass [lindex $items 3]
-       set decomp [lindex $items 5]
-
-       set cclass_map($index) $cclass
-       #set decomp_map($index) $cclass
-
-       if {$decomp != ""} {
-           if {[string index [lindex $decomp 0] 0] == "<"} {
-               set decomp1 [lreplace $decomp 0 0]
-               set decomp {}
-               foreach ch $decomp1 {
-                   scan $ch %x ch
-                   lappend decomp $ch
-               }
-               set decomp_map($index) $decomp
-           } else {
-               switch -- [llength $decomp] {
-                   1 {
-                       scan $decomp %x ch
-                       set decomp_map($index) $ch
-                   }
-                   2 {
-                       scan $decomp "%x %x" ch1 ch2
-                       set decomp [list $ch1 $ch2]
-                       set decomp_map($index) $decomp
-                       # hackish
-                       if {(![info exists cclass_map($ch1)] || \
-                                $cclass_map($ch1) == 0) && \
-                               ![info exists exclusions($index)]} {
-                           if {[info exists comp_first($ch1)]} {
-                               incr comp_first($ch1)
-                           } else {
-                               set comp_first($ch1) 1
-                           }
-                           if {[info exists comp_second($ch2)]} {
-                               incr comp_second($ch2)
-                           } else {
-                               set comp_second($ch2) 1
-                           }
-                           set comp_map($decomp) $index
-                       } else {
-                           puts "Excluded $index"
-                       }
-                   }
-                   default {
-                       puts "Bad canonical decomposition: $line"
-                   } 
-               }
-           }
-
-           #puts "[format 0x%0.4x $index]\t$cclass\t$decomp_map($index)"
-       }
-    }
-    #puts [array get comp_first]
-    #puts [array get comp_second]
-}
-
-proc uni::buildTables {} {
-    variable cclass_shift
-    variable decomp_shift
-    variable comp_shift
-
-    variable cclass_map
-    variable cclass_pmap {}
-    variable cclass_pages {}
-    variable decomp_map
-    variable decomp_pmap {}
-    variable decomp_pages {}
-    variable decomp_list {}
-    variable comp_map
-    variable comp_pmap {}
-    variable comp_pages {}
-    variable comp_first
-    variable comp_second
-    variable comp_first_list {}
-    variable comp_second_list {}
-    variable comp_x_list {}
-    variable comp_y_list {}
-    variable comp_both_map {}
-
-    set cclass_info {}
-    set decomp_info {}
-    set comp_info {}
-    
-    set cclass_mask [expr {(1 << $cclass_shift) - 1}]
-    set decomp_mask [expr {(1 << $decomp_shift) - 1}]
-    set comp_mask [expr {(1 << $comp_shift) - 1}]
-
-    foreach comp [array names comp_map] {
-       set ch1 [lindex $comp 0]
-       if {[info exists comp_first($ch1)] && $comp_first($ch1) > 0 && \
-               [info exists comp_second($ch1)] && $comp_second($ch1) > 0} {
-           if {[lsearch -exact $comp_x_list $ch1] < 0} {
-               set i [llength $comp_x_list]
-               lappend comp_x_list $ch1
-               set comp_info_map($ch1) $i
-               lappend comp_y_list $ch1
-               set comp_info_map($ch1) $i
-               puts "There should be no symbols which appears on"
-               puts "both first and second place in composition"
-               exit
-           }
-       }
-    }
-
-    foreach comp [array names comp_map] {
-       set ch1 [lindex $comp 0]
-       set ch2 [lindex $comp 1]
-
-       if {$comp_first($ch1) == 1 && ![info exists comp_second($ch1)]} {
-           set i [llength $comp_first_list]
-           lappend comp_first_list [list $ch2 $comp_map($comp)]
-           set comp_info_map($ch1) [expr {$i | (1 << 16)}]
-       } elseif {$comp_second($ch2) == 1 && ![info exists comp_first($ch2)]} {
-           set i [llength $comp_second_list]
-           lappend comp_second_list [list $ch1 $comp_map($comp)]
-           set comp_info_map($ch2) [expr {$i | (1 << 16) | (1 << 17)}]
-       } else {
-           if {[lsearch -exact $comp_x_list $ch1] < 0} {
-               set i [llength $comp_x_list]
-               lappend comp_x_list $ch1
-               set comp_info_map($ch1) $i
-           }
-           if {[lsearch -exact $comp_y_list $ch2] < 0} {
-               set i [llength $comp_y_list]
-               lappend comp_y_list $ch2
-               set comp_info_map($ch2) [expr {$i | (1 << 17)}]
-           }
-       }
-    }
-
-    set next 0
-
-    for {set i 0} {$i <= 0x10ffff} {incr i} {
-       #set gIndex [getGroup [getValue $i]]
-
-       set cclass_offset [expr {$i & $cclass_mask}]
-
-       if {[info exists cclass_map($i)]} {
-           set cclass $cclass_map($i)
-       } else {
-           set cclass 0
-       }
-       lappend cclass_info $cclass
-
-       if {$cclass_offset == $cclass_mask} {
-           addPage cclass_pmap cclass_pages $cclass_info
-           set cclass_info {}
-       }
-
-
-       set decomp_offset [expr {$i & $decomp_mask}]
-
-       if {[info exists decomp_map($i)]} {
-           set decomp $decomp_map($i)
-           set b 1
-           while {$b} {
-               set b 0
-               for {set j 0} {$j < [llength $decomp]} {incr j} {
-                   if {[info exists \
-                            decomp_map([set ch1 [lindex $decomp $j]])]} {
-                       #puts -$decomp
-                       set decomp [eval [list lreplace $decomp $j $j] \
-                                       $decomp_map($ch1)]
-                       #puts +$decomp
-                       set b 1
-                   }
-               }
-           }
-
-           if {[info exists decomp_used($decomp)]} {
-               lappend decomp_info $decomp_used($decomp)
-           } else {
-               set val [expr {([llength $decomp] << 16) + \
-                                  [llength $decomp_list]}]
-               #set val [expr {[llength $decomp_list]}]
-               lappend decomp_info $val
-               set decomp_used($decomp) $val
-               #puts "$val $decomp"
-               foreach d $decomp {
-                   lappend decomp_list $d
-               }
-           }
-       } else {
-           lappend decomp_info -1
-       }
-
-       if {$decomp_offset == $decomp_mask} {
-           addPage decomp_pmap decomp_pages $decomp_info
-           set decomp_info {}
-       }
-
-
-       set comp_offset [expr {$i & $comp_mask}]
-
-       if {[info exists comp_info_map($i)]} {
-           set comp $comp_info_map($i)
-       } else {
-           set comp -1
-       }
-       lappend comp_info $comp
-
-       if {$comp_offset == $comp_mask} {
-           addPage comp_pmap comp_pages $comp_info
-           set comp_info {}
-       }
-    }
-
-    #puts [array get decomp_map]
-    #puts $decomp_list
-
-    return
-}
-
-proc uni::main {} {
-    global argc argv0 argv
-    variable cclass_shift
-    variable cclass_pmap
-    variable cclass_pages
-    variable decomp_shift
-    variable decomp_pmap
-    variable decomp_pages
-    variable decomp_list
-    variable comp_shift
-    variable comp_map
-    variable comp_pmap
-    variable comp_pages
-    variable comp_first_list
-    variable comp_second_list
-    variable comp_x_list
-    variable comp_y_list
-    variable pages
-    variable groups {}
-    variable titleCount
-
-    if {$argc != 3} {
-       puts stderr "\nusage: $argv0 <datafile> <exclusionsfile> <outdir>\n"
-       exit 1
-    }
-    set f [open [lindex $argv 1] r]
-    set data [read $f]
-    close $f
-
-    load_exclusions $data
-
-    set f [open [lindex $argv 0] r]
-    set data [read $f]
-    close $f
-
-    load_tables $data
-    buildTables
-    #puts "X = [llength $pMap]  Y= [llength $pages]  A= [llength $groups]"
-    #set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}]
-    #puts "shift = 6, space = $size"
-    #puts "title case count = $titleCount"
-
-    set f [open [file join [lindex $argv 2] uni_norm.c] w]
-    fconfigure $f -translation lf
-    puts $f "/*
- * uni_norm.c --
- *
- *     Declarations of Unicode character information tables.  This file is
- *     automatically generated by the uni_parse2.tcl script.  Do not
- *     modify this file by hand.
- *
- * Copyright (c) 1998 by Scriptics Corporation.
- * All rights reserved.
- *
- * Modified for ejabberd by Alexey Shchepin
- *
- * RCS: @(#) \$Id\$
- */
-
-/*
- * A 16-bit Unicode character is split into two parts in order to index
- * into the following tables.  The lower CCLASS_OFFSET_BITS comprise an offset
- * into a page of characters.  The upper bits comprise the page number.
- */
-
-#define CCLASS_OFFSET_BITS $cclass_shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char cclassPageMap\[\] = {"
-    set line "    "
-    set last [expr {[llength $cclass_pmap] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       append line [lindex $cclass_pmap $i]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 70} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * The cclassGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a combining class number.
- */
-
-static unsigned char cclassGroupMap\[\] = {"
-    set line "    "
-    set lasti [expr {[llength $cclass_pages] - 1}]
-    for {set i 0} {$i <= $lasti} {incr i} {
-       set page [lindex $cclass_pages $i]
-       set lastj [expr {[llength $page] - 1}]
-       for {set j 0} {$j <= $lastj} {incr j} {
-           append line [lindex $page $j]
-           if {$j != $lastj || $i != $lasti} {
-               append line ", "
-           }
-           if {[string length $line] > 70} {
-               puts $f $line
-               set line "    "
-           }
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-#define GetUniCharCClass(ch) (cclassGroupMap\[(cclassPageMap\[(((int)(ch)) & 0x1fffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\])
-
-
-#define DECOMP_OFFSET_BITS $decomp_shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char decompPageMap\[\] = {"
-    set line "    "
-    set last [expr {[llength $decomp_pmap] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       append line [lindex $decomp_pmap $i]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 70} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * The decompGroupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a length and
- * shift of decomposition sequence in decompList
- */
-
-static int decompGroupMap\[\] = {"
-    set line "    "
-    set lasti [expr {[llength $decomp_pages] - 1}]
-    for {set i 0} {$i <= $lasti} {incr i} {
-       set page [lindex $decomp_pages $i]
-       set lastj [expr {[llength $page] - 1}]
-       for {set j 0} {$j <= $lastj} {incr j} {
-           append line [lindex $page $j]
-           if {$j != $lastj || $i != $lasti} {
-               append line ", "
-           }
-           if {[string length $line] > 70} {
-               puts $f $line
-               set line "    "
-           }
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * List of decomposition sequences
- */
-
-static int decompList\[\] = {"
-    set line "    "
-    set last [expr {[llength $decomp_list] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       set val [lindex $decomp_list $i]
-
-       append line [format "%d" $val]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 70} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-
-/*
- * This macro extracts the information about a character from the
- * Unicode character tables.
- */
-
-#define GetUniCharDecompInfo(ch) (decompGroupMap\[(decompPageMap\[(((int)(ch)) & 0x1fffff) >> DECOMP_OFFSET_BITS\] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))\])
-
-#define GetDecompShift(info) ((info) & 0xffff)
-#define GetDecompLen(info) ((info) >> 16)
-
-
-#define COMP_OFFSET_BITS $comp_shift
-
-/*
- * The pageMap is indexed by page number and returns an alternate page number
- * that identifies a unique page of characters.  Many Unicode characters map
- * to the same alternate page number.
- */
-
-static unsigned char compPageMap\[\] = {"
-    set line "    "
-    set last [expr {[llength $comp_pmap] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       append line [lindex $comp_pmap $i]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 70} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * The groupMap is indexed by combining the alternate page number with
- * the page offset and returns a group number that identifies a unique
- * set of character attributes.
- */
-
-static int compGroupMap\[\] = {"
-    set line "    "
-    set lasti [expr {[llength $comp_pages] - 1}]
-    for {set i 0} {$i <= $lasti} {incr i} {
-       set page [lindex $comp_pages $i]
-       set lastj [expr {[llength $page] - 1}]
-       for {set j 0} {$j <= $lastj} {incr j} {
-           append line [lindex $page $j]
-           if {$j != $lastj || $i != $lasti} {
-               append line ", "
-           }
-           if {[string length $line] > 70} {
-               puts $f $line
-               set line "    "
-           }
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * Lists of compositions for characters that appears only in one composition
- */
-
-static int compFirstList\[\]\[2\] = {"
-    set line "    "
-    set last [expr {[llength $comp_first_list] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       set val [lindex $comp_first_list $i]
-
-       append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 60} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-static int compSecondList\[\]\[2\] = {"
-    set line "    "
-    set last [expr {[llength $comp_second_list] - 1}]
-    for {set i 0} {$i <= $last} {incr i} {
-       set val [lindex $comp_second_list $i]
-
-       append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]]
-       if {$i != $last} {
-           append line ", "
-       }
-       if {[string length $line] > 60} {
-           puts $f $line
-           set line "    "
-       }
-    }
-    puts $f $line
-    puts $f "};
-
-/*
- * Compositions matrix
- */
-
-static int compBothList\[[llength $comp_x_list]\]\[[llength $comp_y_list]\] = {"
-    set lastx [expr {[llength $comp_x_list] - 1}]
-    set lasty [expr {[llength $comp_y_list] - 1}]
-    for {set i 0} {$i <= $lastx} {incr i} {
-       puts $f "    \{"
-       set line "        "
-       for {set j 0} {$j <= $lasty} {incr j} {
-           set comp [list [lindex $comp_x_list $i] [lindex $comp_y_list $j]]
-           if {[info exists comp_map($comp)]} {
-               set val $comp_map($comp)
-           } else {
-               set val 0
-           }
-           
-           append line [format "%d" $val]
-           if {$j != $lasty} {
-               append line ", "
-           }
-           if {[string length $line] > 70} {
-               puts $f $line
-               set line "        "
-           }
-       }
-       puts $f $line
-       if {$j != $lasty} {
-           puts $f "    \},"
-       } else {
-           puts $f "    \}"
-       }
-    }
-    puts $f "};
-
-
-#define GetUniCharCompInfo(ch) (compGroupMap\[(compPageMap\[(((int)(ch)) & 0x1fffff) >> COMP_OFFSET_BITS\] << COMP_OFFSET_BITS) | ((ch) & ((1 << COMP_OFFSET_BITS)-1))\])
-
-#define CompSingleMask (1 << 16)
-#define CompMask ((1 << 16) - 1)
-#define CompSecondMask (1 << 17)
-"
-
-    close $f
-}
-
-uni::main
-
-return
diff --git a/src/stun/Makefile.in b/src/stun/Makefile.in
deleted file mode 100644 (file)
index e77da84..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id: Makefile.in 1453 2008-07-16 16:58:42Z badlop $
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/stun/Makefile.win32 b/src/stun/Makefile.win32
deleted file mode 100644 (file)
index e70aba9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\stun_codec.beam ..\ejabberd_stun.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\stun_codec.beam : stun_codec.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) stun_codec.erl
-
-$(OUTDIR)\ejabberd_stun.beam : ejabberd_stun.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_stun.erl
diff --git a/src/stun/ejabberd_stun.erl b/src/stun/ejabberd_stun.erl
deleted file mode 100644 (file)
index 1046fff..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : ejabberd_stun.erl
-%%% Author  : Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%% Description : RFC5389 implementation.
-%%%               Currently only Binding usage is supported.
-%%%
-%%% Created :  8 Aug 2009 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%-------------------------------------------------------------------
--module(ejabberd_stun).
-
--behaviour(gen_fsm).
-
-%% API
--export([start_link/2, start/2, socket_type/0,
-        udp_recv/5]).
-
-%% gen_fsm callbacks
--export([init/1, handle_event/3, handle_sync_event/4,
-        handle_info/3, terminate/3, code_change/4]).
-
-%% gen_fsm states
--export([wait_for_tls/2, session_established/2]).
-
--include("ejabberd.hrl").
-
--include("stun.hrl").
-
--define(MAX_BUF_SIZE, 64 * 1024).
-
--define(TIMEOUT, 10000).
-
--record(state,
-       {sock                  :: inet:socket() | tls:tls_socket(),
-         sock_mod = gen_tcp    :: gen_udp | gen_tcp | tls,
-         certfile              :: binary(),
-         peer = {{0,0,0,0}, 0} :: {inet:ip_address(), inet:port_number()},
-         tref = make_ref()     :: reference(),
-        buf = <<>>            :: binary()}).
-
-%%====================================================================
-%% API
-%%====================================================================
-start({gen_tcp, Sock}, Opts) ->
-    supervisor:start_child(ejabberd_stun_sup, [Sock, Opts]).
-
-start_link(Sock, Opts) ->
-    gen_fsm:start_link(?MODULE, [Sock, Opts], []).
-
-socket_type() -> raw.
-
-udp_recv(Sock, Addr, Port, Data, _Opts) ->
-    case stun_codec:decode(Data) of
-      {ok, Msg, <<>>} ->
-         ?DEBUG("got:~n~p", [Msg]),
-         case process(Addr, Port, Msg) of
-           RespMsg when is_record(RespMsg, stun) ->
-               ?DEBUG("sent:~n~p", [RespMsg]),
-               Data1 = stun_codec:encode(RespMsg),
-               gen_udp:send(Sock, Addr, Port, Data1);
-           _ -> ok
-         end;
-      _ -> ok
-    end.
-
-%%====================================================================
-%% gen_fsm callbacks
-%%====================================================================
-init([Sock, Opts]) ->
-    case inet:peername(Sock) of
-      {ok, Addr} ->
-         inet:setopts(Sock, [{active, once}]),
-         TRef = erlang:start_timer(?TIMEOUT, self(), stop),
-         State = #state{sock = Sock, peer = Addr, tref = TRef},
-         case proplists:get_value(certfile, Opts) of
-           undefined -> {ok, session_established, State};
-           CertFile ->
-               {ok, wait_for_tls, State#state{certfile = CertFile}}
-         end;
-      Err -> Err
-    end.
-
-wait_for_tls(Event, State) ->
-    ?INFO_MSG("unexpected event in wait_for_tls: ~p",
-             [Event]),
-    {next_state, wait_for_tls, State}.
-
-session_established(Msg, State)
-    when is_record(Msg, stun) ->
-    ?DEBUG("got:~n~p", [Msg]),
-    {Addr, Port} = State#state.peer,
-    case process(Addr, Port, Msg) of
-      Resp when is_record(Resp, stun) ->
-         ?DEBUG("sent:~n~p", [Resp]),
-         Data = stun_codec:encode(Resp),
-         (State#state.sock_mod):send(State#state.sock, Data);
-      _ -> ok
-    end,
-    {next_state, session_established, State};
-session_established(Event, State) ->
-    ?INFO_MSG("unexpected event in session_established: ~p",
-             [Event]),
-    {next_state, session_established, State}.
-
-handle_event(_Event, StateName, State) ->
-    {next_state, StateName, State}.
-
-handle_sync_event(_Event, _From, StateName, State) ->
-    {reply, {error, badarg}, StateName, State}.
-
-handle_info({tcp, Sock, TLSData}, wait_for_tls,
-           State) ->
-    Buf = <<(State#state.buf)/binary, TLSData/binary>>,
-    case Buf of
-      _ when byte_size(Buf) < 3 ->
-         {next_state, wait_for_tls,
-          update_state(State#state{buf = Buf})};
-      <<_:16, 1, _/binary>> ->
-         TLSOpts = [{certfile, State#state.certfile}],
-         {ok, TLSSock} = tls:tcp_to_tls(Sock, TLSOpts),
-         NewState = State#state{sock = TLSSock, buf = <<>>,
-                                sock_mod = tls},
-         case tls:recv_data(TLSSock, Buf) of
-           {ok, Data} ->
-               process_data(session_established, NewState, Data);
-           _Err -> {stop, normal, NewState}
-         end;
-      _ -> process_data(session_established, State, TLSData)
-    end;
-handle_info({tcp, _Sock, TLSData}, StateName,
-           #state{sock_mod = tls} = State) ->
-    case tls:recv_data(State#state.sock, TLSData) of
-      {ok, Data} -> process_data(StateName, State, Data);
-      _Err -> {stop, normal, State}
-    end;
-handle_info({tcp, _Sock, Data}, StateName, State) ->
-    process_data(StateName, State, Data);
-handle_info({tcp_closed, _Sock}, _StateName, State) ->
-    ?DEBUG("connection reset by peer", []),
-    {stop, normal, State};
-handle_info({tcp_error, _Sock, Reason}, _StateName,
-           State) ->
-    ?DEBUG("connection error: ~p", [Reason]),
-    {stop, normal, State};
-handle_info({timeout, TRef, stop}, _StateName,
-           #state{tref = TRef} = State) ->
-    {stop, normal, State};
-handle_info(Info, StateName, State) ->
-    ?INFO_MSG("unexpected info: ~p", [Info]),
-    {next_state, StateName, State}.
-
-terminate(_Reason, _StateName, State) ->
-    catch (State#state.sock_mod):close(State#state.sock),
-    ok.
-
-code_change(_OldVsn, StateName, State, _Extra) ->
-    {ok, StateName, State}.
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
-process(Addr, Port,
-       #stun{class = request, unsupported = []} = Msg) ->
-    Resp = prepare_response(Msg),
-    if Msg#stun.method == (?STUN_METHOD_BINDING) ->
-          case stun_codec:version(Msg) of
-            old ->
-                Resp#stun{class = response,
-                          'MAPPED-ADDRESS' = {Addr, Port}};
-            new ->
-                Resp#stun{class = response,
-                          'XOR-MAPPED-ADDRESS' = {Addr, Port}}
-          end;
-       true ->
-          Resp#stun{class = error,
-                    'ERROR-CODE' = {405, <<"Method Not Allowed">>}}
-    end;
-process(_Addr, _Port, #stun{class = request} = Msg) ->
-    Resp = prepare_response(Msg),
-    Resp#stun{class = error,
-             'UNKNOWN-ATTRIBUTES' = Msg#stun.unsupported,
-             'ERROR-CODE' = {420, stun_codec:reason(420)}};
-process(_Addr, _Port, _Msg) -> pass.
-
-prepare_response(Msg) ->
-    Version = <<"ejabberd ", (iolist_to_binary(?VERSION))/binary>>,
-    #stun{method = Msg#stun.method, magic = Msg#stun.magic,
-         trid = Msg#stun.trid, 'SOFTWARE' = Version}.
-
-process_data(NextStateName, #state{buf = Buf} = State,
-            Data) ->
-    NewBuf = <<Buf/binary, Data/binary>>,
-    case stun_codec:decode(NewBuf) of
-      {ok, Msg, Tail} ->
-         gen_fsm:send_event(self(), Msg),
-         process_data(NextStateName, State#state{buf = <<>>},
-                      Tail);
-      empty ->
-         NewState = State#state{buf = <<>>},
-         {next_state, NextStateName, update_state(NewState)};
-      more when byte_size(NewBuf) < (?MAX_BUF_SIZE) ->
-         NewState = State#state{buf = NewBuf},
-         {next_state, NextStateName, update_state(NewState)};
-      _ -> {stop, normal, State}
-    end.
-
-update_state(#state{sock = Sock} = State) ->
-    case State#state.sock_mod of
-      gen_tcp -> inet:setopts(Sock, [{active, once}]);
-      SockMod -> SockMod:setopts(Sock, [{active, once}])
-    end,
-    cancel_timer(State#state.tref),
-    TRef = erlang:start_timer(?TIMEOUT, self(), stop),
-    State#state{tref = TRef}.
-
-cancel_timer(TRef) ->
-    case erlang:cancel_timer(TRef) of
-      false ->
-         receive {timeout, TRef, _} -> ok after 0 -> ok end;
-      _ -> ok
-    end.
diff --git a/src/stun/stun.hrl b/src/stun/stun.hrl
deleted file mode 100644 (file)
index 251cf83..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : stun.hrl
-%%% Author  : Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%% Description : STUN values
-%%% Created :  8 Aug 2009 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%-------------------------------------------------------------------
--define(STUN_MAGIC, 16#2112a442).
-
-%% I know, this is terrible. Refer to 'STUN Message Structure' of
-%% RFC5389 to understand this.
--define(STUN_METHOD(Type),
-       Type band 15872 bsr 2 bor (Type band 224 bsr 1) bor
-         Type band 15).
-
--define(STUN_CLASS(Type),
-       Type band 256 bsr 7 bor (Type band 16 bsr 4)).
-
--define(STUN_TYPE(C, M),
-%% Comprehension-required range (0x0000-0x7FFF)
-%% Comprehension-optional range (0x8000-0xFFFF)
-       M band 3968 bsl 2 bor (M band 112 bsl 1) bor M band 15
-         bor (C band 2 bsl 7 bor (C band 1 bsl 4))).
-
--define(is_required(A), A =< 32767).
-
--define(STUN_METHOD_BINDING, 1).
-
--define(STUN_ATTR_MAPPED_ADDRESS, 1).
-
--define(STUN_ATTR_USERNAME, 6).
-
--define(STUN_ATTR_MESSAGE_INTEGRITY, 8).
-
--define(STUN_ATTR_ERROR_CODE, 9).
-
--define(STUN_ATTR_UNKNOWN_ATTRIBUTES, 10).
-
--define(STUN_ATTR_REALM, 20).
-
--define(STUN_ATTR_NONCE, 21).
-
--define(STUN_ATTR_XOR_MAPPED_ADDRESS, 32).
-
--define(STUN_ATTR_SOFTWARE, 32802).
-
--define(STUN_ATTR_ALTERNATE_SERVER, 32803).
-
--define(STUN_ATTR_FINGERPRINT, 32808).
-
--record(stun,
-       {class = request :: request | response | error | indication,
-         method = ?STUN_METHOD_BINDING :: non_neg_integer(),
-         magic = ?STUN_MAGIC :: non_neg_integer(),
-         trid = 0 :: non_neg_integer() ,
-        unsupported = [] :: [non_neg_integer()],
-         'SOFTWARE',
-         'ALTERNATE-SERVER',
-        'MAPPED-ADDRESS',
-         'XOR-MAPPED-ADDRESS',
-         'USERNAME',
-        'REALM',
-         'NONCE',
-         'MESSAGE-INTEGRITY',
-         'ERROR-CODE',
-        'UNKNOWN-ATTRIBUTES' = []}).
-
-%% Workarounds.
-%%-define(NO_PADDING, true).
-
diff --git a/src/stun/stun_codec.erl b/src/stun/stun_codec.erl
deleted file mode 100644 (file)
index 4d489e0..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File    : stun_codec.erl
-%%% Author  : Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%% Description : STUN codec
-%%% Created :  7 Aug 2009 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%-------------------------------------------------------------------
--module(stun_codec).
-
-%% API
--export([decode/1, encode/1, version/1, reason/1,
-        pp/1]).
-
-%% Tests
--export([test_udp/2, test_tcp/2, test_tls/2,
-        test_public/0]).
-
--include("stun.hrl").
-
-%%====================================================================
-%% API
-%%====================================================================
-decode(<<0:2, Type:14, Len:16, Magic:32, TrID:96,
-        Body:Len/binary, Tail/binary>>) ->
-    case catch decode(Type, Magic, TrID, Body) of
-      {'EXIT', _} -> {error, unparsed};
-      Res -> {ok, Res, Tail}
-    end;
-decode(<<0:2, _/binary>>) -> more;
-decode(<<>>) -> empty;
-decode(_) -> {error, unparsed}.
-
-encode(#stun{class = Class, method = Method,
-            magic = Magic, trid = TrID} =
-          Msg) ->
-    ClassCode = case Class of
-                 request -> 0;
-                 indication -> 1;
-                 response -> 2;
-                 error -> 3
-               end,
-    Type = (?STUN_TYPE(ClassCode, Method)),
-    Attrs = enc_attrs(Msg),
-    Len = byte_size(Attrs),
-    <<0:2, Type:14, Len:16, Magic:32, TrID:96,
-      Attrs/binary>>.
-
-pp(Term) -> io_lib_pretty:print(Term, fun pp/2).
-
-version(#stun{magic = ?STUN_MAGIC}) -> new;
-version(#stun{}) -> old.
-
-reason(300) -> <<"Try Alternate">>;
-reason(400) -> <<"Bad Request">>;
-reason(401) -> <<"Unauthorized">>;
-reason(420) -> <<"Unknown Attribute">>;
-reason(438) -> <<"Stale Nonce">>;
-reason(500) -> <<"Server Error">>;
-reason(_) -> <<"Undefined Error">>.
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-decode(Type, Magic, TrID, Body) ->
-    Method = (?STUN_METHOD(Type)),
-    Class = case ?STUN_CLASS(Type) of
-             0 -> request;
-             1 -> indication;
-             2 -> response;
-             3 -> error
-           end,
-    dec_attrs(Body,
-             #stun{class = Class, method = Method, magic = Magic,
-                   trid = TrID}).
-
-dec_attrs(<<Type:16, Len:16, Rest/binary>>, Msg) ->
-    PaddLen = padd_len(Len),
-    <<Val:Len/binary, _:PaddLen, Tail/binary>> = Rest,
-    NewMsg = dec_attr(Type, Val, Msg),
-    if Type == (?STUN_ATTR_MESSAGE_INTEGRITY) -> NewMsg;
-       true -> dec_attrs(Tail, NewMsg)
-    end;
-dec_attrs(<<>>, Msg) -> Msg.
-
-enc_attrs(Msg) ->
-    iolist_to_binary([enc_attr(?STUN_ATTR_SOFTWARE,
-                              Msg#stun.'SOFTWARE'),
-                     enc_addr(?STUN_ATTR_MAPPED_ADDRESS,
-                              Msg#stun.'MAPPED-ADDRESS'),
-                     enc_xor_addr(?STUN_ATTR_XOR_MAPPED_ADDRESS,
-                                  Msg#stun.magic, Msg#stun.trid,
-                                  Msg#stun.'XOR-MAPPED-ADDRESS'),
-                     enc_addr(?STUN_ATTR_ALTERNATE_SERVER,
-                              Msg#stun.'ALTERNATE-SERVER'),
-                     enc_attr(?STUN_ATTR_USERNAME, Msg#stun.'USERNAME'),
-                     enc_attr(?STUN_ATTR_REALM, Msg#stun.'REALM'),
-                     enc_attr(?STUN_ATTR_NONCE, Msg#stun.'NONCE'),
-                     enc_error_code(Msg#stun.'ERROR-CODE'),
-                     enc_unknown_attrs(Msg#stun.'UNKNOWN-ATTRIBUTES')]).
-
-dec_attr(?STUN_ATTR_MAPPED_ADDRESS, Val, Msg) ->
-    <<_, Family, Port:16, AddrBin/binary>> = Val,
-    Addr = dec_addr(Family, AddrBin),
-    Msg#stun{'MAPPED-ADDRESS' = {Addr, Port}};
-dec_attr(?STUN_ATTR_XOR_MAPPED_ADDRESS, Val, Msg) ->
-    <<_, Family, XPort:16, XAddr/binary>> = Val,
-    Magic = Msg#stun.magic,
-    Port = XPort bxor (Magic bsr 16),
-    Addr = dec_xor_addr(Family, Magic, Msg#stun.trid,
-                       XAddr),
-    Msg#stun{'XOR-MAPPED-ADDRESS' = {Addr, Port}};
-dec_attr(?STUN_ATTR_SOFTWARE, Val, Msg) ->
-    Msg#stun{'SOFTWARE' = Val};
-dec_attr(?STUN_ATTR_USERNAME, Val, Msg) ->
-    Msg#stun{'USERNAME' = Val};
-dec_attr(?STUN_ATTR_REALM, Val, Msg) ->
-    Msg#stun{'REALM' = Val};
-dec_attr(?STUN_ATTR_NONCE, Val, Msg) ->
-    Msg#stun{'NONCE' = Val};
-dec_attr(?STUN_ATTR_MESSAGE_INTEGRITY, Val, Msg) ->
-    Msg#stun{'MESSAGE-INTEGRITY' = Val};
-dec_attr(?STUN_ATTR_ALTERNATE_SERVER, Val, Msg) ->
-    <<_, Family, Port:16, Address/binary>> = Val,
-    IP = dec_addr(Family, Address),
-    Msg#stun{'ALTERNATE-SERVER' = {IP, Port}};
-dec_attr(?STUN_ATTR_ERROR_CODE, Val, Msg) ->
-    <<_:21, Class:3, Number:8, Reason/binary>> = Val,
-    if Class >= 3, Class =< 6, Number >= 0, Number =< 99 ->
-          Code = Class * 100 + Number,
-          Msg#stun{'ERROR-CODE' = {Code, Reason}}
-    end;
-dec_attr(?STUN_ATTR_UNKNOWN_ATTRIBUTES, Val, Msg) ->
-    Attrs = dec_unknown_attrs(Val, []),
-    Msg#stun{'UNKNOWN-ATTRIBUTES' = Attrs};
-dec_attr(Attr, _Val, #stun{unsupported = Attrs} = Msg)
-    when Attr =< 32767 ->
-    Msg#stun{unsupported = [Attr | Attrs]};
-dec_attr(_Attr, _Val, Msg) -> Msg.
-
-dec_addr(1, <<A1, A2, A3, A4>>) -> {A1, A2, A3, A4};
-dec_addr(2,
-        <<A1:16, A2:16, A3:16, A4:16, A5:16, A6:16, A7:16,
-          A8:16>>) ->
-    {A1, A2, A3, A4, A5, A6, A7, A8}.
-
-dec_xor_addr(1, Magic, _TrID, <<XAddr:32>>) ->
-    Addr = XAddr bxor Magic, dec_addr(1, <<Addr:32>>);
-dec_xor_addr(2, Magic, TrID, <<XAddr:128>>) ->
-    Addr = XAddr bxor (Magic bsl 96 bor TrID),
-    dec_addr(2, <<Addr:128>>).
-
-dec_unknown_attrs(<<Attr:16, Tail/binary>>, Acc) ->
-    dec_unknown_attrs(Tail, [Attr | Acc]);
-dec_unknown_attrs(<<>>, Acc) -> lists:reverse(Acc).
-
-enc_attr(_Attr, undefined) -> <<>>;
-enc_attr(Attr, Val) ->
-    Len = byte_size(Val),
-    PaddLen = padd_len(Len),
-    <<Attr:16, Len:16, Val/binary, 0:PaddLen>>.
-
-enc_addr(_Type, undefined) -> <<>>;
-enc_addr(Type, {{A1, A2, A3, A4}, Port}) ->
-    enc_attr(Type, <<0, 1, Port:16, A1, A2, A3, A4>>);
-enc_addr(Type,
-        {{A1, A2, A3, A4, A5, A6, A7, A8}, Port}) ->
-    enc_attr(Type,
-            <<0, 2, Port:16, A1:16, A2:16, A3:16, A4:16, A5:16,
-              A6:16, A7:16, A8:16>>).
-
-enc_xor_addr(_Type, _Magic, _TrID, undefined) -> <<>>;
-enc_xor_addr(Type, Magic, _TrID,
-            {{A1, A2, A3, A4}, Port}) ->
-    XPort = Port bxor (Magic bsr 16),
-    <<Addr:32>> = <<A1, A2, A3, A4>>,
-    XAddr = Addr bxor Magic,
-    enc_attr(Type, <<0, 1, XPort:16, XAddr:32>>);
-enc_xor_addr(Type, Magic, TrID,
-            {{A1, A2, A3, A4, A5, A6, A7, A8}, Port}) ->
-    XPort = Port bxor (Magic bsr 16),
-    <<Addr:128>> = <<A1:16, A2:16, A3:16, A4:16, A5:16,
-                    A6:16, A7:16, A8:16>>,
-    XAddr = Addr bxor (Magic bsl 96 bor TrID),
-    enc_attr(Type, <<0, 2, XPort:16, XAddr:128>>).
-
-enc_error_code(undefined) -> <<>>;
-enc_error_code({Code, Reason}) ->
-    Class = Code div 100,
-    Number = Code rem 100,
-    enc_attr(?STUN_ATTR_ERROR_CODE,
-            <<0:21, Class:3, Number:8, Reason/binary>>).
-
-enc_unknown_attrs([]) -> <<>>;
-enc_unknown_attrs(Attrs) ->
-    enc_attr(?STUN_ATTR_UNKNOWN_ATTRIBUTES,
-%%====================================================================
-%% Auxiliary functions
-%%====================================================================
-            iolist_to_binary([<<Attr:16>> || Attr <- Attrs])).
-
-pp(Tag, N) -> try pp1(Tag, N) catch _:_ -> no end.
-
-pp1(stun, N) ->
-    N = record_info(size, stun) - 1,
-    record_info(fields, stun);
-pp1(_, _) -> no.
-
-%% Workaround for stupid clients.
--ifdef(NO_PADDING).
-
-padd_len(_Len) -> 0.
-
--else.
-
-padd_len(Len) ->
-    case Len rem 4 of
-      0 -> 0;
-      N -> 8 * (4 - N)
-    end.
-
--endif.
-
-%%====================================================================
-%% Test functions
-%%====================================================================
-bind_msg() ->
-    Msg = #stun{method = ?STUN_METHOD_BINDING,
-               class = request, trid = random:uniform(1 bsl 96),
-               'SOFTWARE' = <<"test">>},
-    encode(Msg).
-
-test_udp(Addr, Port) -> test(Addr, Port, gen_udp).
-
-test_tcp(Addr, Port) -> test(Addr, Port, gen_tcp).
-
-test_tls(Addr, Port) -> test(Addr, Port, ssl).
-
-test(Addr, Port, Mod) ->
-    Res = case Mod of
-           gen_udp -> Mod:open(0, [binary, {active, false}]);
-           _ ->
-               Mod:connect(Addr, Port, [binary, {active, false}], 1000)
-         end,
-    case Res of
-      {ok, Sock} ->
-         if Mod == gen_udp ->
-                Mod:send(Sock, Addr, Port, bind_msg());
-            true -> Mod:send(Sock, bind_msg())
-         end,
-         case Mod:recv(Sock, 0, 1000) of
-           {ok, {_, _, Data}} -> try_dec(Data);
-           {ok, Data} -> try_dec(Data);
-           Err -> io:format("err: ~p~n", [Err])
-         end,
-         Mod:close(Sock);
-      Err -> io:format("err: ~p~n", [Err])
-    end.
-
-try_dec(Data) ->
-    case decode(Data) of
-      {ok, Msg, _} -> io:format("got:~n~s~n", [pp(Msg)]);
-      Err -> io:format("err: ~p~n", [Err])
-    end.
-
-public_servers() ->
-    [{"stun.ekiga.net", 3478, 3478, 5349},
-     {"stun.ideasip.com", 3478, 3478, 5349},
-     {"stun.softjoys.com", 3478, 3478, 5349},
-     {"stun.voipbuster.com", 3478, 3478, 5349},
-     {"stun.voxgratia.org", 3478, 3478, 5349},
-     {"stunserver.org", 3478, 3478, 5349},
-     {"stun.sipgate.net", 10000, 10000, 5349},
-     {"numb.viagenie.ca", 3478, 3478, 5349},
-     {"stun.ipshka.com", 3478, 3478, 5349},
-     {"localhost", 3478, 5349, 5349}].
-
-test_public() ->
-    ssl:start(),
-    lists:foreach(fun ({Addr, UDPPort, TCPPort, TLSPort}) ->
-                         io:format("trying ~s:~p on UDP... ", [Addr, UDPPort]),
-                         test_udp(Addr, UDPPort),
-                         io:format("trying ~s:~p on TCP... ", [Addr, TCPPort]),
-                         test_tcp(Addr, TCPPort),
-                         io:format("trying ~s:~p on TLS... ", [Addr, TLSPort]),
-                         test_tls(Addr, TLSPort)
-                 end,
-                 public_servers()).
diff --git a/src/tls/Makefile.in b/src/tls/Makefile.in
deleted file mode 100644 (file)
index ab5e32d..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-SSL_CFLAGS = @SSL_CFLAGS@
-SSL_LIBS = @SSL_LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-# Assume Linux-style dynamic library flags
-DYNAMIC_LIB_CFLAGS = -fpic -shared
-ifeq ($(shell uname),Darwin)
-    DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
-endif
-ifeq ($(shell uname),SunOs)
-    DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
-endif
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-ifeq (@md2@, true)
-  EFLAGS+=-DHAVE_MD2
-  ERLANG_CFLAGS += -DHAVE_MD2
-endif
-
-ERLSHLIBS = ../tls_drv.so ../sha_drv.so
-OUTDIR = ..
-SOURCES = $(wildcard *.erl)
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-
-all:    $(BEAMS) $(ERLSHLIBS)
-
-$(OUTDIR)/%.beam:       %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-#all:  $(ERLSHLIBS)
-#      erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt
-
-$(ERLSHLIBS):  ../%.so:        %.c
-       $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \
-               $(subst ../,,$(subst .so,.c,$@)) \
-               $(LIBS) \
-               $(SSL_LIBS) \
-               $(SSL_CFLAGS) \
-               $(ERLANG_LIBS) \
-               $(ERLANG_CFLAGS) \
-               -o $@ \
-               $(DYNAMIC_LIB_CFLAGS)
-
-clean:
-       rm -f $(BEAMS) $(ERLSHLIBS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
diff --git a/src/tls/Makefile.win32 b/src/tls/Makefile.win32
deleted file mode 100644 (file)
index f5a3dba..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\tls.beam
-
-SOURCE = tls_drv.c sha_drv.c
-OBJECT = tls_drv.o sha_drv.o
-DLL    = $(OUTDIR)\tls_drv.dll $(OUTPUT)\sha_drv.dll
-
-ALL : $(DLL) $(BEAMS)
-
-CLEAN :
-       -@erase $(DLL)
-       -@erase $(OUTDIR)\tls_drv.exp
-       -@erase $(OUTDIR)\tls_drv.lib
-       -@erase $(OUTDIR)\sha_drv.exp
-       -@erase $(OUTDIR)\sha_drv.lib
-       -@erase $(OBJECT)
-       -@erase $(BEAMS)
-
-$(OUTDIR)\tls.beam : tls.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) tls.erl
-
-CC=cl.exe
-CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(OPENSSL_DIR)\include" -I"."
-
-LD=link.exe
-LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(OPENSSL_DIR)\lib\VC\ssleay32MD.lib" "$(OPENSSL_DIR)\lib\VC\libeay32MD.lib" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
-
-$(DLL) : $(OBJECT)
-       $(LD) $(LD_FLAGS) -out:$@ $<
-
-$(OBJECT) : $(SOURCE)
-       $(CC) $(CC_FLAGS) -c -Fo$@ $<
-
diff --git a/src/tls/sha_drv.c b/src/tls/sha_drv.c
deleted file mode 100644 (file)
index 3558f79..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013   ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include <erl_driver.h>
-#include <openssl/sha.h>
-#ifdef HAVE_MD2
-#include <openssl/md2.h>
-#endif
-
-/*
- * R15B changed several driver callbacks to use ErlDrvSizeT and
- * ErlDrvSSizeT typedefs instead of int.
- * This provides missing typedefs on older OTP versions.
- */
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int ErlDrvSizeT;
-typedef int ErlDrvSSizeT;
-#endif
-
-static ErlDrvData sha_drv_start(ErlDrvPort port, char *buf)
-{
-  set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-  return NULL;
-}
-
-static ErlDrvSSizeT sha_drv_control(ErlDrvData handle,
-                          unsigned int command,
-                          char *buf, ErlDrvSizeT len,
-                          char **rbuf, ErlDrvSizeT rlen)
-{
-  ErlDrvBinary *b = NULL;
-
-  switch (command) {
-#ifdef HAVE_MD2
-  case 2:
-    rlen = MD2_DIGEST_LENGTH;
-    b = driver_alloc_binary(rlen);
-    if (b) MD2((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
-    break;
-#endif
-  case 224:
-    rlen = SHA224_DIGEST_LENGTH;
-    b = driver_alloc_binary(rlen);
-    if (b) SHA224((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
-    break;
-  case 256:
-    rlen = SHA256_DIGEST_LENGTH;
-    b = driver_alloc_binary(rlen);
-    if (b) SHA256((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
-    break;
-  case 384:
-    rlen = SHA384_DIGEST_LENGTH;
-    b = driver_alloc_binary(rlen);
-    if (b) SHA384((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
-    break;
-  case 512:
-    rlen = SHA512_DIGEST_LENGTH;
-    b = driver_alloc_binary(rlen);
-    if (b) SHA512((unsigned char*)buf, len, (unsigned char*)b->orig_bytes);
-    break;
-  };
-  
-  if (b) {
-    *rbuf = (char *)b;
-  } else {
-    *rbuf = NULL;
-    rlen = 0;
-  };
-
-  return rlen;
-}
-
-ErlDrvEntry sha_driver_entry = {
-  NULL,                        /* F_PTR init, N/A */
-  sha_drv_start,        /* L_PTR start, called when port is opened */
-  NULL,                 /* F_PTR stop, called when port is closed */
-  NULL,                        /* F_PTR output, called when erlang has sent */
-  NULL,                        /* F_PTR ready_input, called when input descriptor ready */
-  NULL,                        /* F_PTR ready_output, called when output descriptor ready */
-  "sha_drv",           /* char *driver_name, the argument to open_port */
-  NULL,                 /* F_PTR finish, called when unloaded */
-  NULL,                        /* handle */
-  sha_drv_control,     /* F_PTR control, port_command callback */
-  NULL,                        /* F_PTR timeout, reserved */
-  NULL,                        /* F_PTR outputv, reserved */
-  /* Added in Erlang/OTP R15B: */
-  NULL,                 /* ready_async */
-  NULL,                 /* flush */
-  NULL,                 /* call */
-  NULL,                 /* event */
-  ERL_DRV_EXTENDED_MARKER,        /* extended_marker */
-  ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */
-  ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */
-  0,                    /* driver_flags */
-  NULL,                 /* handle2 */
-  NULL,                 /* process_exit */
-  NULL                  /* stop_select */
-};
-
-DRIVER_INIT(sha_drv) /* must match name in driver_entry */
-{
-  return &sha_driver_entry;
-}
diff --git a/src/tls/stdint.h b/src/tls/stdint.h
deleted file mode 100755 (executable)
index e032ff1..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-// ISO C9x  compliant stdint.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
-// 
-//  Copyright (c) 2006-2008 Alexander Chemeris
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//   1. Redistributions of source code must retain the above copyright notice,
-//      this list of conditions and the following disclaimer.
-// 
-//   2. Redistributions in binary form must reproduce the above copyright
-//      notice, this list of conditions and the following disclaimer in the
-//      documentation and/or other materials provided with the distribution.
-// 
-//   3. The name of the author may be used to endorse or promote products
-//      derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_STDINT_H_ // [
-#define _MSC_STDINT_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#include <limits.h>
-
-// For Visual Studio 6 in C++ mode wrap <wchar.h> include with 'extern "C++" {}'
-// or compiler give many errors like this:
-//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#if (_MSC_VER < 1300) && defined(__cplusplus)
-   extern "C++" {
-#endif 
-#     include <wchar.h>
-#if (_MSC_VER < 1300) && defined(__cplusplus)
-   }
-#endif
-
-// Define _W64 macros to mark types changing their size, like intptr_t.
-#ifndef _W64
-#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
-#     define _W64 __w64
-#  else
-#     define _W64
-#  endif
-#endif
-
-
-// 7.18.1 Integer types
-
-// 7.18.1.1 Exact-width integer types
-typedef __int8            int8_t;
-typedef __int16           int16_t;
-typedef __int32           int32_t;
-typedef __int64           int64_t;
-typedef unsigned __int8   uint8_t;
-typedef unsigned __int16  uint16_t;
-typedef unsigned __int32  uint32_t;
-typedef unsigned __int64  uint64_t;
-
-// 7.18.1.2 Minimum-width integer types
-typedef int8_t    int_least8_t;
-typedef int16_t   int_least16_t;
-typedef int32_t   int_least32_t;
-typedef int64_t   int_least64_t;
-typedef uint8_t   uint_least8_t;
-typedef uint16_t  uint_least16_t;
-typedef uint32_t  uint_least32_t;
-typedef uint64_t  uint_least64_t;
-
-// 7.18.1.3 Fastest minimum-width integer types
-typedef int8_t    int_fast8_t;
-typedef int16_t   int_fast16_t;
-typedef int32_t   int_fast32_t;
-typedef int64_t   int_fast64_t;
-typedef uint8_t   uint_fast8_t;
-typedef uint16_t  uint_fast16_t;
-typedef uint32_t  uint_fast32_t;
-typedef uint64_t  uint_fast64_t;
-
-// 7.18.1.4 Integer types capable of holding object pointers
-#ifdef _WIN64 // [
-   typedef __int64           intptr_t;
-   typedef unsigned __int64  uintptr_t;
-#else // _WIN64 ][
-   typedef _W64 int               intptr_t;
-   typedef _W64 unsigned int      uintptr_t;
-#endif // _WIN64 ]
-
-// 7.18.1.5 Greatest-width integer types
-typedef int64_t   intmax_t;
-typedef uint64_t  uintmax_t;
-
-
-// 7.18.2 Limits of specified-width integer types
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
-
-// 7.18.2.1 Limits of exact-width integer types
-#define INT8_MIN     ((int8_t)_I8_MIN)
-#define INT8_MAX     _I8_MAX
-#define INT16_MIN    ((int16_t)_I16_MIN)
-#define INT16_MAX    _I16_MAX
-#define INT32_MIN    ((int32_t)_I32_MIN)
-#define INT32_MAX    _I32_MAX
-#define INT64_MIN    ((int64_t)_I64_MIN)
-#define INT64_MAX    _I64_MAX
-#define UINT8_MAX    _UI8_MAX
-#define UINT16_MAX   _UI16_MAX
-#define UINT32_MAX   _UI32_MAX
-#define UINT64_MAX   _UI64_MAX
-
-// 7.18.2.2 Limits of minimum-width integer types
-#define INT_LEAST8_MIN    INT8_MIN
-#define INT_LEAST8_MAX    INT8_MAX
-#define INT_LEAST16_MIN   INT16_MIN
-#define INT_LEAST16_MAX   INT16_MAX
-#define INT_LEAST32_MIN   INT32_MIN
-#define INT_LEAST32_MAX   INT32_MAX
-#define INT_LEAST64_MIN   INT64_MIN
-#define INT_LEAST64_MAX   INT64_MAX
-#define UINT_LEAST8_MAX   UINT8_MAX
-#define UINT_LEAST16_MAX  UINT16_MAX
-#define UINT_LEAST32_MAX  UINT32_MAX
-#define UINT_LEAST64_MAX  UINT64_MAX
-
-// 7.18.2.3 Limits of fastest minimum-width integer types
-#define INT_FAST8_MIN    INT8_MIN
-#define INT_FAST8_MAX    INT8_MAX
-#define INT_FAST16_MIN   INT16_MIN
-#define INT_FAST16_MAX   INT16_MAX
-#define INT_FAST32_MIN   INT32_MIN
-#define INT_FAST32_MAX   INT32_MAX
-#define INT_FAST64_MIN   INT64_MIN
-#define INT_FAST64_MAX   INT64_MAX
-#define UINT_FAST8_MAX   UINT8_MAX
-#define UINT_FAST16_MAX  UINT16_MAX
-#define UINT_FAST32_MAX  UINT32_MAX
-#define UINT_FAST64_MAX  UINT64_MAX
-
-// 7.18.2.4 Limits of integer types capable of holding object pointers
-#ifdef _WIN64 // [
-#  define INTPTR_MIN   INT64_MIN
-#  define INTPTR_MAX   INT64_MAX
-#  define UINTPTR_MAX  UINT64_MAX
-#else // _WIN64 ][
-#  define INTPTR_MIN   INT32_MIN
-#  define INTPTR_MAX   INT32_MAX
-#  define UINTPTR_MAX  UINT32_MAX
-#endif // _WIN64 ]
-
-// 7.18.2.5 Limits of greatest-width integer types
-#define INTMAX_MIN   INT64_MIN
-#define INTMAX_MAX   INT64_MAX
-#define UINTMAX_MAX  UINT64_MAX
-
-// 7.18.3 Limits of other integer types
-
-#ifdef _WIN64 // [
-#  define PTRDIFF_MIN  _I64_MIN
-#  define PTRDIFF_MAX  _I64_MAX
-#else  // _WIN64 ][
-#  define PTRDIFF_MIN  _I32_MIN
-#  define PTRDIFF_MAX  _I32_MAX
-#endif  // _WIN64 ]
-
-#define SIG_ATOMIC_MIN  INT_MIN
-#define SIG_ATOMIC_MAX  INT_MAX
-
-#ifndef SIZE_MAX // [
-#  ifdef _WIN64 // [
-#     define SIZE_MAX  _UI64_MAX
-#  else // _WIN64 ][
-#     define SIZE_MAX  _UI32_MAX
-#  endif // _WIN64 ]
-#endif // SIZE_MAX ]
-
-// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
-#ifndef WCHAR_MIN // [
-#  define WCHAR_MIN  0
-#endif  // WCHAR_MIN ]
-#ifndef WCHAR_MAX // [
-#  define WCHAR_MAX  _UI16_MAX
-#endif  // WCHAR_MAX ]
-
-#define WINT_MIN  0
-#define WINT_MAX  _UI16_MAX
-
-#endif // __STDC_LIMIT_MACROS ]
-
-
-// 7.18.4 Limits of other integer types
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val)  val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val)  val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-#define INTMAX_C   INT64_C
-#define UINTMAX_C  UINT64_C
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-
-#endif // _MSC_STDINT_H_ ]
diff --git a/src/tls/tls.erl b/src/tls/tls.erl
deleted file mode 100644 (file)
index 74a6270..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : tls.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : Interface to openssl
-%%% Created : 24 Jul 2004 by Alexey Shchepin <alexey@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(tls).
-
--author('alexey@process-one.net').
-
--behaviour(gen_server).
-
--export([start/0, start_link/0, tcp_to_tls/2,
-        tls_to_tcp/1, send/2, recv/2, recv/3, recv_data/2,
-        setopts/2, sockname/1, peername/1,
-        controlling_process/2, close/1, get_peer_certificate/1,
-        get_verify_result/1, get_cert_verify_string/2, test/0]).
-
-%% Internal exports, call-back functions.
--export([init/1, handle_call/3, handle_cast/2,
-        handle_info/2, code_change/3, terminate/2]).
-
--include("ejabberd.hrl").
-
--define(SET_CERTIFICATE_FILE_ACCEPT, 1).
-
--define(SET_CERTIFICATE_FILE_CONNECT, 2).
-
--define(SET_ENCRYPTED_INPUT, 3).
-
--define(SET_DECRYPTED_OUTPUT, 4).
-
--define(GET_ENCRYPTED_OUTPUT, 5).
-
--define(GET_DECRYPTED_INPUT, 6).
-
--define(GET_PEER_CERTIFICATE, 7).
-
--define(GET_VERIFY_RESULT, 8).
-
--define(VERIFY_NONE, 65536).
-
--record(tlssock, {tcpsock :: inet:socket(),
-                  tlsport :: port()}).
-
--type tls_socket() :: #tlssock{}.
-
--type cert() :: any(). %% TODO
-
--export_type([tls_socket/0]).
-
-start() ->
-    gen_server:start({local, ?MODULE}, ?MODULE, [], []).
-
-start_link() ->
-    gen_server:start_link({local, ?MODULE}, ?MODULE, [],
-                         []).
-
-init([]) ->
-    case erl_ddll:load_driver(ejabberd:get_so_path(),
-                             tls_drv)
-       of
-      ok -> ok;
-      {error, already_loaded} -> ok
-    end,
-    Port = open_port({spawn, "tls_drv"}, [binary]),
-    Res = port_control(Port, ?SET_CERTIFICATE_FILE_ACCEPT,
-                      <<"./ssl.pem", 0>>),
-    case Res of
-      <<0>> -> {ok, Port};
-      <<1, Error/binary>> -> {error, (Error)}
-    end.
-
-%%% --------------------------------------------------------
-%%% The call-back functions.
-%%% --------------------------------------------------------
-
-handle_call(_, _, State) -> {noreply, State}.
-
-handle_cast(_, State) -> {noreply, State}.
-
-handle_info({'EXIT', Port, Reason}, Port) ->
-    {stop, {port_died, Reason}, Port};
-handle_info({'EXIT', _Pid, _Reason}, Port) ->
-    {noreply, Port};
-handle_info(_, State) -> {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) -> {ok, State}.
-
-terminate(_Reason, Port) -> Port ! {self, close}, ok.
-
--spec tcp_to_tls(inet:socket(),
-                 [{atom(), any()}]) -> {'error','no_certfile' | binary()} |
-                                       {ok, tls_socket()}.
-
-tcp_to_tls(TCPSocket, Options) ->
-    case lists:keysearch(certfile, 1, Options) of
-      {value, {certfile, CertFile}} ->
-         case erl_ddll:load_driver(ejabberd:get_so_path(),
-                                   tls_drv)
-             of
-           ok -> ok;
-           {error, already_loaded} -> ok
-         end,
-         Port = open_port({spawn, "tls_drv"}, [binary]),
-         Flags = case lists:member(verify_none, Options) of
-                   true -> ?VERIFY_NONE;
-                   false -> 0
-                 end,
-         Command = case lists:member(connect, Options) of
-                     true -> ?SET_CERTIFICATE_FILE_CONNECT;
-                     false -> ?SET_CERTIFICATE_FILE_ACCEPT
-                   end,
-          CertFile1 = iolist_to_binary(CertFile),
-         case port_control(Port, Command bor Flags,
-                           <<CertFile1/binary, 0>>)
-             of
-           <<0>> ->
-               {ok, #tlssock{tcpsock = TCPSocket, tlsport = Port}};
-           <<1, Error/binary>> -> {error, (Error)}
-         end;
-      false -> {error, no_certfile}
-    end.
-
--spec tls_to_tcp(tls_socket()) -> inet:socket().
-
-tls_to_tcp(#tlssock{tcpsock = TCPSocket,
-                   tlsport = Port}) ->
-    port_close(Port), TCPSocket.
-
-recv(Socket, Length) -> recv(Socket, Length, infinity).
-
--spec recv(tls_socket(), non_neg_integer(),
-           timeout()) -> {error, inet:posix()} |
-                         {error, binary()} |
-                         {ok, binary()}.
-
-recv(#tlssock{tcpsock = TCPSocket, tlsport = Port} =
-        TLSSock,
-     Length, Timeout) ->
-    case port_control(Port, ?GET_DECRYPTED_INPUT,
-                     <<Length:32>>)
-       of
-      <<0>> ->
-         case gen_tcp:recv(TCPSocket, 0, Timeout) of
-           {ok, Packet} -> recv_data(TLSSock, Packet, Length);
-           {error, _Reason} = Error -> Error
-         end;
-      <<0, In/binary>> -> {ok, In};
-      <<1, Error/binary>> -> {error, (Error)}
-    end.
-
-recv_data(TLSSock, Packet) ->
-    recv_data(TLSSock, Packet, 0).
-
--spec recv_data(tls_socket(), binary(),
-                non_neg_integer()) -> {error, inet:posix() | binary()} |
-                                      {ok, binary()}.
-
-recv_data(TLSSock, Packet, Length) ->
-    case catch recv_data1(TLSSock, Packet, Length) of
-      {'EXIT', Reason} -> {error, Reason};
-      Res -> Res
-    end.
-
-recv_data1(#tlssock{tcpsock = TCPSocket,
-                   tlsport = Port},
-          Packet, Length) ->
-    case port_control(Port, ?SET_ENCRYPTED_INPUT, Packet) of
-      <<0>> ->
-         case port_control(Port, ?GET_DECRYPTED_INPUT,
-                           <<Length:32>>)
-             of
-           <<0, In/binary>> ->
-               case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of
-                 <<0, Out/binary>> ->
-                     case gen_tcp:send(TCPSocket, Out) of
-                       ok -> {ok, In};
-                       Error -> Error
-                     end;
-                 <<1, Error/binary>> -> {error, (Error)}
-               end;
-           <<1, Error/binary>> -> {error, (Error)}
-         end;
-      <<1, Error/binary>> -> {error, (Error)}
-    end.
-
--spec send(tls_socket(), binary()) -> ok | {error, inet:posix() |
-                                            binary() | timeout}.
-
-send(#tlssock{tcpsock = TCPSocket, tlsport = Port} =
-        TLSSock,
-     Packet) ->
-    case port_control(Port, ?SET_DECRYPTED_OUTPUT, Packet)
-       of
-      <<0>> ->
-         case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of
-           <<0, Out/binary>> -> gen_tcp:send(TCPSocket, Out);
-           <<1, Error/binary>> -> {error, (Error)}
-         end;
-      <<1, Error/binary>> -> {error, (Error)};
-      <<2>> -> % Dirty hack
-         receive
-           {timeout, _Timer, _} -> {error, timeout}
-           after 100 -> send(TLSSock, Packet)
-         end
-    end.
-
--spec setopts(tls_socket(), list()) -> ok | {error, inet:posix()}.
-
-setopts(#tlssock{tcpsock = TCPSocket}, Opts) ->
-    inet:setopts(TCPSocket, Opts).
-
--spec sockname(tls_socket()) -> {ok, {inet:ip_address(), inet:port_number()}} |
-                                {error, inet:posix()}.
-
-sockname(#tlssock{tcpsock = TCPSocket}) ->
-    inet:sockname(TCPSocket).
-
-peername(#tlssock{tcpsock = TCPSocket}) ->
-    inet:peername(TCPSocket).
-
-controlling_process(#tlssock{tcpsock = TCPSocket},
-                   Pid) ->
-    gen_tcp:controlling_process(TCPSocket, Pid).
-
-close(#tlssock{tcpsock = TCPSocket, tlsport = Port}) ->
-    gen_tcp:close(TCPSocket), port_close(Port).
-
--spec get_peer_certificate(tls_socket()) -> error | {ok, cert()}.
-
-get_peer_certificate(#tlssock{tlsport = Port}) ->
-    case port_control(Port, ?GET_PEER_CERTIFICATE, []) of
-      <<0, BCert/binary>> ->
-         case catch public_key:pkix_decode_cert(BCert, plain)
-             of
-           {ok, Cert} -> {ok, Cert};
-           {'Certificate', _, _, _} = Cert -> {ok, Cert};
-           _ -> error
-         end;
-      <<1>> -> error
-    end.
-
--spec get_verify_result(tls_socket()) -> byte().
-
-get_verify_result(#tlssock{tlsport = Port}) ->
-    <<Res>> = port_control(Port, ?GET_VERIFY_RESULT, []),
-    Res.
-
-test() ->
-    case erl_ddll:load_driver(ejabberd:get_so_path(),
-                             tls_drv)
-       of
-      ok -> ok;
-      {error, already_loaded} -> ok
-    end,
-    Port = open_port({spawn, "tls_drv"}, [binary]),
-    ?PRINT("open_port: ~p~n", [Port]),
-    PCRes = port_control(Port, ?SET_CERTIFICATE_FILE_ACCEPT,
-                        <<"./ssl.pem", 0>>),
-    ?PRINT("port_control: ~p~n", [PCRes]),
-    {ok, ListenSocket} = gen_tcp:listen(1234,
-                                       [binary, {packet, 0}, {active, true},
-                                        {reuseaddr, true}, {nodelay, true}]),
-    ?PRINT("listen: ~p~n", [ListenSocket]),
-    {ok, Socket} = gen_tcp:accept(ListenSocket),
-    ?PRINT("accept: ~p~n", [Socket]),
-    loop(Port, Socket).
-
-loop(Port, Socket) ->
-    receive
-      {tcp, Socket, Data} ->
-         Res = port_control(Port, ?SET_ENCRYPTED_INPUT, Data),
-         ?PRINT("SET_ENCRYPTED_INPUT: ~p~n", [Res]),
-         DIRes = port_control(Port, ?GET_DECRYPTED_INPUT, Data),
-         ?PRINT("GET_DECRYPTED_INPUT: ~p~n", [DIRes]),
-         case DIRes of
-           <<0, In/binary>> -> ?PRINT("input: ~s~n", [(In)]);
-           <<1, DIError/binary>> ->
-               ?PRINT("GET_DECRYPTED_INPUT error: ~p~n", [(DIError)])
-         end,
-         EORes = port_control(Port, ?GET_ENCRYPTED_OUTPUT, Data),
-         ?PRINT("GET_ENCRYPTED_OUTPUT: ~p~n", [EORes]),
-         case EORes of
-           <<0, Out/binary>> -> gen_tcp:send(Socket, Out);
-           <<1, EOError/binary>> ->
-               ?PRINT("GET_ENCRYPTED_OUTPUT error: ~p~n", [(EOError)])
-         end,
-         loop(Port, Socket);
-      Msg ->
-         ?PRINT("receive: ~p~n", [Msg]), loop(Port, Socket)
-    end.
-
--spec get_cert_verify_string(number(), cert()) -> binary().
-
-get_cert_verify_string(CertVerifyRes, Cert) ->
-    BCert = public_key:pkix_encode('Certificate', Cert,
-                                  plain),
-    IsSelfsigned = public_key:pkix_is_self_signed(BCert),
-    case {CertVerifyRes, IsSelfsigned} of
-      {21, true} -> <<"self-signed certificate">>;
-      _ -> cert_verify_code(CertVerifyRes)
-    end.
-
-%% http://www.openssl.org/docs/apps/verify.html
-cert_verify_code(0) -> <<"ok">>;
-cert_verify_code(2) ->
-    <<"unable to get issuer certificate">>;
-cert_verify_code(3) ->
-    <<"unable to get certificate CRL">>;
-cert_verify_code(4) ->
-    <<"unable to decrypt certificate's signature">>;
-cert_verify_code(5) ->
-    <<"unable to decrypt CRL's signature">>;
-cert_verify_code(6) ->
-    <<"unable to decode issuer public key">>;
-cert_verify_code(7) ->
-    <<"certificate signature failure">>;
-cert_verify_code(8) -> <<"CRL signature failure">>;
-cert_verify_code(9) ->
-    <<"certificate is not yet valid">>;
-cert_verify_code(10) -> <<"certificate has expired">>;
-cert_verify_code(11) -> <<"CRL is not yet valid">>;
-cert_verify_code(12) -> <<"CRL has expired">>;
-cert_verify_code(13) ->
-    <<"format error in certificate's notBefore "
-      "field">>;
-cert_verify_code(14) ->
-    <<"format error in certificate's notAfter "
-      "field">>;
-cert_verify_code(15) ->
-    <<"format error in CRL's lastUpdate field">>;
-cert_verify_code(16) ->
-    <<"format error in CRL's nextUpdate field">>;
-cert_verify_code(17) -> <<"out of memory">>;
-cert_verify_code(18) -> <<"self signed certificate">>;
-cert_verify_code(19) ->
-    <<"self signed certificate in certificate "
-      "chain">>;
-cert_verify_code(20) ->
-    <<"unable to get local issuer certificate">>;
-cert_verify_code(21) ->
-    <<"unable to verify the first certificate">>;
-cert_verify_code(22) ->
-    <<"certificate chain too long">>;
-cert_verify_code(23) -> <<"certificate revoked">>;
-cert_verify_code(24) -> <<"invalid CA certificate">>;
-cert_verify_code(25) ->
-    <<"path length constraint exceeded">>;
-cert_verify_code(26) ->
-    <<"unsupported certificate purpose">>;
-cert_verify_code(27) -> <<"certificate not trusted">>;
-cert_verify_code(28) -> <<"certificate rejected">>;
-cert_verify_code(29) -> <<"subject issuer mismatch">>;
-cert_verify_code(30) ->
-    <<"authority and subject key identifier "
-      "mismatch">>;
-cert_verify_code(31) ->
-    <<"authority and issuer serial number mismatch">>;
-cert_verify_code(32) ->
-    <<"key usage does not include certificate "
-      "signing">>;
-cert_verify_code(50) ->
-    <<"application verification failure">>;
-cert_verify_code(X) ->
-    <<"Unknown OpenSSL error code: ", (jlib:integer_to_binary(X))/binary>>.
diff --git a/src/tls/tls_drv.c b/src/tls/tls_drv.c
deleted file mode 100644 (file)
index c35f3f0..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * ejabberd, Copyright (C) 2002-2013   ProcessOne
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <erl_driver.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-
-#define BUF_SIZE 1024
-
-typedef struct {
-      ErlDrvPort port;
-      BIO *bio_read;
-      BIO *bio_write;
-      SSL *ssl;
-} tls_data;
-
-#ifdef _WIN32
-typedef unsigned __int32 uint32_t;
-#endif
-
-#ifndef SSL_OP_NO_TICKET
-#define SSL_OP_NO_TICKET 0
-#endif
-
-#define CIPHERS "DEFAULT:!EXPORT:!LOW:!SSLv2"
-
-/*
- * R15B changed several driver callbacks to use ErlDrvSizeT and
- * ErlDrvSSizeT typedefs instead of int.
- * This provides missing typedefs on older OTP versions.
- */
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int ErlDrvSizeT;
-typedef int ErlDrvSSizeT;
-#endif
-
-/*
- * str_hash is based on the public domain code from
- * http://www.burtleburtle.net/bob/hash/doobs.html
- */
-static uint32_t str_hash(char *s)
-{
-   unsigned char *key = (unsigned char *)s;
-   uint32_t hash = 0;
-   size_t i;
-
-   for (i = 0; key[i] != 0; i++) {
-      hash += key[i];
-      hash += (hash << 10);
-      hash ^= (hash >> 6);
-   }
-   hash += (hash << 3);
-   hash ^= (hash >> 11);
-   hash += (hash << 15);
-   return hash;
-}
-
-/* Linear hashing */
-
-#define MIN_LEVEL 8
-#define MAX_LEVEL 20
-
-struct bucket {
-      uint32_t hash;
-      char *key_file;
-      time_t mtime;
-      SSL_CTX *ssl_ctx;
-      struct bucket *next;
-};
-
-struct hash_table {
-      int split;
-      int level;
-      struct bucket **buckets;
-      int size;
-};
-
-struct hash_table ht;
-
-static void init_hash_table()
-{
-   size_t size = 1 << (MIN_LEVEL + 1);
-   size_t i;
-   ht.buckets = (struct bucket **)driver_alloc(sizeof(struct bucket *) * size);
-   ht.split = 0;
-   ht.level = MIN_LEVEL;
-   for (i = 0; i < size; i++)
-      ht.buckets[i] = NULL;
-   
-}
-
-static void hash_table_insert(char *key_file, time_t mtime,
-                            SSL_CTX *ssl_ctx)
-{
-   int level, split;
-   uint32_t hash = str_hash(key_file);
-   size_t bucket;
-   int do_split = 0;
-   struct bucket *el;
-   struct bucket *new_bucket_el;
-
-   split = ht.split;
-   level = ht.level;
-
-   bucket = hash & ((1 << level) - 1);
-   if (bucket < split)
-      bucket = hash & ((1 << (level + 1)) - 1);
-
-   el = ht.buckets[bucket];
-   while (el != NULL) {
-      if (el->hash == hash && strcmp(el->key_file, key_file) == 0) {
-        el->mtime = mtime;
-        if (el->ssl_ctx != NULL)
-           SSL_CTX_free(el->ssl_ctx);
-        el->ssl_ctx = ssl_ctx;
-        break;
-      }
-      el = el->next;
-   }
-
-   if (el == NULL) {
-      if (ht.buckets[bucket] != NULL)
-        do_split = !0;
-
-      new_bucket_el = (struct bucket *)driver_alloc(sizeof(struct bucket));
-      new_bucket_el->hash = hash;
-      new_bucket_el->key_file = (char *)driver_alloc(strlen(key_file) + 1);
-      strcpy(new_bucket_el->key_file, key_file);
-      new_bucket_el->mtime = mtime;
-      new_bucket_el->ssl_ctx = ssl_ctx;
-      new_bucket_el->next = ht.buckets[bucket];
-      ht.buckets[bucket] = new_bucket_el;
-   }
-
-   if (do_split) {
-      struct bucket **el_ptr = &ht.buckets[split];
-      size_t new_bucket = split + (1 << level);
-      while (*el_ptr != NULL) {
-        uint32_t hash = (*el_ptr)->hash;
-        if ((hash & ((1 << (level + 1)) - 1)) == new_bucket) {
-           struct bucket *moved_el = *el_ptr;
-           *el_ptr = (*el_ptr)->next;
-           moved_el->next = ht.buckets[new_bucket];
-           ht.buckets[new_bucket] = moved_el;
-        } else
-           el_ptr = &(*el_ptr)->next;
-      }
-      split++;
-      if (split == 1 << level) {
-        size_t size;
-        size_t i;
-        split = 0;
-        level++;
-        size = 1 << (level + 1);
-        ht.split = split;
-        ht.level = level;
-        ht.buckets = (struct bucket **)
-           driver_realloc(ht.buckets, sizeof(struct bucket *) * size);
-        for (i = 1 << level; i < size; i++)
-           ht.buckets[i] = NULL;
-      } else
-        ht.split = split;
-   }
-}
-
-static SSL_CTX *hash_table_lookup(char *key_file, time_t *pmtime)
-{
-   int level, split;
-   uint32_t hash = str_hash(key_file);
-   size_t bucket;
-   struct bucket *el;
-
-   split = ht.split;
-   level = ht.level;
-
-   bucket = hash & ((1 << level) - 1);
-   if (bucket < split)
-      bucket = hash & ((1 << (level + 1)) - 1);
-
-   el = ht.buckets[bucket];
-   while (el != NULL) {
-      if (el->hash == hash && strcmp(el->key_file, key_file) == 0) {
-        *pmtime = el->mtime;
-        return el->ssl_ctx;
-      }
-      el = el->next;
-   }
-
-   return NULL;
-}
-
-
-static ErlDrvData tls_drv_start(ErlDrvPort port, char *buff)
-{
-   tls_data *d = (tls_data *)driver_alloc(sizeof(tls_data));
-   d->port = port;
-   d->bio_read = NULL;
-   d->bio_write = NULL;
-   d->ssl = NULL;
-
-   set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
-
-   return (ErlDrvData)d;
-}
-
-static void tls_drv_stop(ErlDrvData handle)
-{
-   tls_data *d = (tls_data *)handle;
-
-   if (d->ssl != NULL)
-      SSL_free(d->ssl);
-
-   driver_free((char *)handle);
-}
-
-static void tls_drv_finish()
-{
-   int level;
-   struct bucket *el;
-   int i;
-
-   level = ht.level;
-   for (i = 0; i < 1 << (level + 1); i++) {
-      el = ht.buckets[i];
-      while (el != NULL) {
-        if (el->ssl_ctx != NULL)
-           SSL_CTX_free(el->ssl_ctx);
-        driver_free(el->key_file);
-        el = el->next;
-      }
-   }
-
-   driver_free(ht.buckets);
-}
-
-static int is_key_file_modified(char *file, time_t *key_file_mtime)
-{
-   struct stat file_stat;
-
-   if (stat(file, &file_stat))
-   {
-      *key_file_mtime = 0;
-      return 1;
-   } else {
-      if (*key_file_mtime != file_stat.st_mtime)
-      {
-        *key_file_mtime = file_stat.st_mtime;
-        return 1;
-      } else
-        return 0;
-   }
-}
-
-static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
-{
-   return 1;
-}
-
-/*
- * ECDHE is enabled only on OpenSSL 1.0.0e and later.
- * See http://www.openssl.org/news/secadv_20110906.txt
- * for details.
- */
-#ifndef OPENSSL_NO_ECDH
-static void setup_ecdh(SSL_CTX *ctx)
-{
-   EC_KEY *ecdh;
-
-   if (SSLeay() < 0x1000005fL) {
-      return;
-   }
-
-   ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-   SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
-   SSL_CTX_set_tmp_ecdh(ctx, ecdh);
-
-   EC_KEY_free(ecdh);
-}
-#endif
-
-#ifndef OPENSSL_NO_DH
-/*
-1024-bit MODP Group with 160-bit prime order subgroup (RFC5114)
------BEGIN DH PARAMETERS-----
-MIIBDAKBgQCxC4+WoIDgHd6S3l6uXVTsUsmfvPsGo8aaap3KUtI7YWBz4oZ1oj0Y
-mDjvHi7mUsAT7LSuqQYRIySXXDzUm4O/rMvdfZDEvXCYSI6cIZpzck7/1vrlZEc4
-+qMaT/VbzMChUa9fDci0vUW/N982XBpl5oz9p21NpwjfH7K8LkpDcQKBgQCk0cvV
-w/00EmdlpELvuZkF+BBN0lisUH/WQGz/FCZtMSZv6h5cQVZLd35pD1UE8hMWAhe0
-sBuIal6RVH+eJ0n01/vX07mpLuGQnQ0iY/gKdqaiTAh6CR9THb8KAWm2oorWYqTR
-jnOvoy13nVkY0IvIhY9Nzvl8KiSFXm7rIrOy5QICAKA=
------END DH PARAMETERS-----
- */
-static unsigned char dh1024_p[] = {
-   0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E,
-   0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6,
-   0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86,
-   0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0,
-   0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C,
-   0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70,
-   0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA,
-   0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0,
-   0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF,
-   0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08,
-   0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71,
-};
-static unsigned char dh1024_g[] = {
-   0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42,
-   0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F,
-   0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E,
-   0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13,
-   0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F,
-   0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1,
-   0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08,
-   0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A,
-   0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59,
-   0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24,
-   0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5,
-};
-
-static void setup_dh(SSL_CTX *ctx)
-{
-   DH *dh;
-
-   dh = DH_new();
-   if (dh == NULL) {
-      return;
-   }
-
-   dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
-   dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
-   if (dh->p == NULL || dh->g == NULL) {
-      DH_free(dh);
-      return;
-   }
-
-   SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
-   SSL_CTX_set_tmp_dh(ctx, dh);
-
-   DH_free(dh);
-}
-#endif
-
-#define SET_CERTIFICATE_FILE_ACCEPT 1
-#define SET_CERTIFICATE_FILE_CONNECT 2
-#define SET_ENCRYPTED_INPUT  3
-#define SET_DECRYPTED_OUTPUT 4
-#define GET_ENCRYPTED_OUTPUT 5
-#define GET_DECRYPTED_INPUT  6
-#define GET_PEER_CERTIFICATE 7
-#define GET_VERIFY_RESULT    8
-#define VERIFY_NONE 0x10000
-
-
-#define die_unless(cond, errstr)                               \
-        if (!(cond))                                           \
-        {                                                      \
-           int errstrlen = strlen(errstr);                     \
-           unsigned long error_code = ERR_get_error();         \
-           char *error_string = error_code ?                   \
-              ERR_error_string(error_code, NULL) :             \
-              NULL;                                            \
-           int error_string_length = error_string ?            \
-              strlen(error_string) : 0;                        \
-           if (error_code)                                     \
-              rlen = errstrlen + error_string_length + 3;      \
-           else                                                \
-              rlen = errstrlen + 1;                            \
-           b = driver_alloc_binary(rlen);                      \
-           b->orig_bytes[0] = 1;                               \
-           strncpy(b->orig_bytes + 1, errstr, errstrlen);      \
-           if (error_code) {                                   \
-              strncpy(b->orig_bytes + 1 + errstrlen,           \
-                      ": ", 2);                                \
-              strncpy(b->orig_bytes + 3 + errstrlen,           \
-                      error_string, error_string_length);      \
-           }                                                   \
-           *rbuf = (char *)b;                                  \
-           return rlen;                                        \
-        }
-
-
-static ErlDrvSSizeT tls_drv_control(ErlDrvData handle,
-                          unsigned int command,
-                          char *buf, ErlDrvSizeT len,
-                          char **rbuf, ErlDrvSizeT rlen)
-{
-   tls_data *d = (tls_data *)handle;
-   int res;
-   int size;
-   ErlDrvBinary *b;
-   X509 *cert;
-   unsigned int flags = command;
-
-   command &= 0xffff;
-
-   ERR_clear_error();
-   switch (command)
-   {
-      case SET_CERTIFICATE_FILE_ACCEPT:
-      case SET_CERTIFICATE_FILE_CONNECT: {
-        time_t mtime = 0;
-        SSL_CTX *ssl_ctx = hash_table_lookup(buf, &mtime);
-        if (is_key_file_modified(buf, &mtime) || ssl_ctx == NULL)
-        {
-           SSL_CTX *ctx;
-
-           hash_table_insert(buf, mtime, NULL);
-
-           ctx = SSL_CTX_new(SSLv23_method());
-           die_unless(ctx, "SSL_CTX_new failed");
-
-           res = SSL_CTX_use_certificate_chain_file(ctx, buf);
-           die_unless(res > 0, "SSL_CTX_use_certificate_file failed");
-
-           res = SSL_CTX_use_PrivateKey_file(ctx, buf, SSL_FILETYPE_PEM);
-           die_unless(res > 0, "SSL_CTX_use_PrivateKey_file failed");
-
-           res = SSL_CTX_check_private_key(ctx);
-           die_unless(res > 0, "SSL_CTX_check_private_key failed");
-
-           SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET);
-
-           SSL_CTX_set_cipher_list(ctx, CIPHERS);
-
-#ifndef OPENSSL_NO_ECDH
-           if (command == SET_CERTIFICATE_FILE_ACCEPT) {
-               setup_ecdh(ctx);
-           }
-#endif
-#ifndef OPENSSL_NO_DH
-           if (command == SET_CERTIFICATE_FILE_ACCEPT) {
-               setup_dh(ctx);
-           }
-#endif
-
-           SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
-           SSL_CTX_set_default_verify_paths(ctx);
-#ifdef SSL_MODE_RELEASE_BUFFERS
-           SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
-#endif
-           /* SSL_CTX_load_verify_locations(ctx, "/etc/ejabberd/ca_certificates.pem", NULL); */
-           /* SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ejabberd/ca_certs/"); */
-
-           /* This IF is commented to allow verification in all cases: */
-           /* if (command == SET_CERTIFICATE_FILE_ACCEPT) */
-           /* { */
-              SSL_CTX_set_verify(ctx,
-                                 SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
-                                 verify_callback);
-           /* } */
-
-           ssl_ctx = ctx;
-           hash_table_insert(buf, mtime, ssl_ctx);
-        }
-
-        d->ssl = SSL_new(ssl_ctx);
-        die_unless(d->ssl, "SSL_new failed");
-
-        if (flags & VERIFY_NONE)
-           SSL_set_verify(d->ssl, SSL_VERIFY_NONE, verify_callback);
-
-        d->bio_read = BIO_new(BIO_s_mem());
-        d->bio_write = BIO_new(BIO_s_mem());
-
-        SSL_set_bio(d->ssl, d->bio_read, d->bio_write);
-
-        if (command == SET_CERTIFICATE_FILE_ACCEPT) {
-           SSL_set_accept_state(d->ssl);
-        } else {
-           SSL_set_connect_state(d->ssl);
-        }
-        break;
-      }
-      case SET_ENCRYPTED_INPUT:
-        die_unless(d->ssl, "SSL not initialized");
-        BIO_write(d->bio_read, buf, len);
-        break;
-      case SET_DECRYPTED_OUTPUT:
-        die_unless(d->ssl, "SSL not initialized");
-        res = SSL_write(d->ssl, buf, len);
-        if (res <= 0) 
-        {
-           res = SSL_get_error(d->ssl, res);
-           if (res == SSL_ERROR_WANT_READ || res == SSL_ERROR_WANT_WRITE) 
-           {
-              b = driver_alloc_binary(1);
-              b->orig_bytes[0] = 2;
-              *rbuf = (char *)b;
-              return 1;
-           } else {
-              die_unless(0, "SSL_write failed");
-           }
-        }
-        break;
-      case GET_ENCRYPTED_OUTPUT:
-        die_unless(d->ssl, "SSL not initialized");
-        size = BIO_ctrl_pending(d->bio_write) + 1;
-        b = driver_alloc_binary(size);
-        b->orig_bytes[0] = 0;
-        BIO_read(d->bio_write, b->orig_bytes + 1, size - 1);
-        *rbuf = (char *)b;
-        return size;
-      case GET_DECRYPTED_INPUT:
-        if (!SSL_is_init_finished(d->ssl))
-        {
-           res = SSL_do_handshake(d->ssl);
-           if (res <= 0)
-              die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ,
-                         "SSL_do_handshake failed");
-        }
-        if (SSL_is_init_finished(d->ssl)) {
-           size_t req_size = 0;
-           if (len == 4)
-           {
-              unsigned char *b = (unsigned char *)buf;
-              req_size =
-                 (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-           }
-           size = BUF_SIZE + 1;
-           rlen = 1;
-           b = driver_alloc_binary(size);
-           b->orig_bytes[0] = 0;
-
-           res = 0;
-
-           while ((req_size == 0 || rlen < req_size + 1) &&
-                  (res = SSL_read(d->ssl,
-                                  b->orig_bytes + rlen,
-                                  (req_size == 0 || req_size + 1 >= size) ?
-                                  size - rlen : req_size + 1 - rlen)) > 0)
-           {
-              //printf("%d bytes of decrypted data read from state machine\r\n",res);
-              rlen += res;
-              if (size - rlen < BUF_SIZE) {
-                 size *= 2;
-                 b = driver_realloc_binary(b, size);
-              }
-           }
-
-           if (res < 0)
-           {
-              int err = SSL_get_error(d->ssl, res);
-
-              if (err == SSL_ERROR_WANT_READ)
-              {
-                 //printf("SSL_read wants more data\r\n");
-                 //return 0;
-              }
-              // TODO
-           }
-           b = driver_realloc_binary(b, rlen);
-           *rbuf = (char *)b;
-           return rlen;
-        }
-        break;
-      case GET_PEER_CERTIFICATE:
-        cert = SSL_get_peer_certificate(d->ssl);
-        if (cert == NULL)
-        {
-           b = driver_alloc_binary(1);
-           b->orig_bytes[0] = 1;
-           *rbuf = (char *)b;
-           return 1;
-        } else {
-           unsigned char *tmp_buf;
-           rlen = i2d_X509(cert, NULL);
-           if (rlen >= 0)
-           {
-              rlen++;
-              b = driver_alloc_binary(rlen);
-              b->orig_bytes[0] = 0;
-              tmp_buf = (unsigned char *)&b->orig_bytes[1];
-              i2d_X509(cert, &tmp_buf);
-              X509_free(cert);
-              *rbuf = (char *)b;
-              return rlen;
-           } else
-              X509_free(cert);
-        }
-        break;
-      case GET_VERIFY_RESULT:
-        b = driver_alloc_binary(1);
-        b->orig_bytes[0] = SSL_get_verify_result(d->ssl);
-        *rbuf = (char *)b;
-        return 1;
-        break;
-   }
-
-   b = driver_alloc_binary(1);
-   b->orig_bytes[0] = 0;
-   *rbuf = (char *)b;
-   return 1;
-}
-
-
-ErlDrvEntry tls_driver_entry = {
-   NULL,                       /* F_PTR init, N/A */
-   tls_drv_start,              /* L_PTR start, called when port is opened */
-   tls_drv_stop,               /* F_PTR stop, called when port is closed */
-   NULL,                       /* F_PTR output, called when erlang has sent */
-   NULL,                       /* F_PTR ready_input, called when input descriptor ready */
-   NULL,                       /* F_PTR ready_output, called when output descriptor ready */
-   "tls_drv",                  /* char *driver_name, the argument to open_port */
-   tls_drv_finish,             /* F_PTR finish, called when unloaded */
-   NULL,                       /* handle */
-   tls_drv_control,            /* F_PTR control, port_command callback */
-   NULL,                       /* F_PTR timeout, reserved */
-   NULL,                       /* F_PTR outputv, reserved */
-  /* Added in Erlang/OTP R15B: */
-  NULL,                 /* ready_async */
-  NULL,                 /* flush */
-  NULL,                 /* call */
-  NULL,                 /* event */
-  ERL_DRV_EXTENDED_MARKER,        /* extended_marker */
-  ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */
-  ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */
-  0,                    /* driver_flags */
-  NULL,                 /* handle2 */
-  NULL,                 /* process_exit */
-  NULL                  /* stop_select */
-};
-
-DRIVER_INIT(tls_drv) /* must match name in driver_entry */
-{
-   OpenSSL_add_ssl_algorithms();
-   SSL_load_error_strings();
-   init_hash_table();
-   return &tls_driver_entry;
-}
-
-
index 3257608f71ad325b43a322f3e227116555c84d6a..fd2ebcc649eb703532f6ad6a0cbe5c32f2bf1f80 100644 (file)
@@ -32,6 +32,7 @@
         translate/2]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 start() ->
     ets:new(translations, [named_table, public]),
diff --git a/src/web/Makefile.in b/src/web/Makefile.in
deleted file mode 100644 (file)
index 151f4c4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# $Id$
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-
-ERLANG_CFLAGS = @ERLANG_CFLAGS@
-ERLANG_LIBS = @ERLANG_LIBS@
-
-EFLAGS += -I ..
-EFLAGS += -pz ..
-
-# make debug=true to compile Erlang module with debug informations.
-ifdef debug
-       EFLAGS+=+debug_info
-endif
-
-SOURCES = $(wildcard *.erl)
-OUTDIR = ..
-BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
-
-all: $(BEAMS)
-
-$(OUTDIR)/%.beam: %.erl
-       @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
-
-clean:
-       rm -f $(BEAMS)
-
-distclean: clean
-       rm -f Makefile
-
-TAGS:
-       etags *.erl
-
diff --git a/src/web/Makefile.win32 b/src/web/Makefile.win32
deleted file mode 100644 (file)
index 411d57c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-include ..\Makefile.inc
-
-EFLAGS = -I .. -pz ..
-
-OUTDIR = ..
-BEAMS = ..\ejabberd_http.beam ..\ejabberd_http_bind.beam ..\ejabberd_http_poll.beam ..\ejabberd_web.beam ..\ejabberd_web_admin.beam ..\mod_http_bind.beam ..\mod_http_fileserver.beam
-
-ALL : $(BEAMS)
-
-CLEAN :
-       -@erase $(BEAMS)
-
-$(OUTDIR)\ejabberd_http.beam : ejabberd_http.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http.erl
-
-$(OUTDIR)\ejabberd_web.beam : ejabberd_web.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_web.erl
-
-$(OUTDIR)\ejabberd_web_admin.beam : ejabberd_web_admin.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_web_admin.erl
-
-$(OUTDIR)\ejabberd_http_bind.beam : ejabberd_http_bind.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http_bind.erl
-
-$(OUTDIR)\ejabberd_http_poll.beam : ejabberd_http_poll.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http_poll.erl
-
-$(OUTDIR)\mod_http_bind.beam : mod_http_bind.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_http_bind.erl
-
-$(OUTDIR)\mod_http_fileserver.beam : mod_http_fileserver.erl
-       erlc -W $(EFLAGS) -o $(OUTDIR) mod_http_fileserver.erl
index a51c4bd21db647b52fdbc146c5bb14b234248cbc..9f80a08deba971b1029f4ff471302452fb2b20aa 100644 (file)
@@ -28,6 +28,7 @@
 -export([get_nameservers/0]).
 
 -include("ejabberd.hrl").
+-include("logger.hrl").
 
 -define(IF_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters\\Interfaces").
 -define(TOP_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters").
diff --git a/src/xml.c b/src/xml.c
deleted file mode 100644 (file)
index 583060c..0000000
--- a/src/xml.c
+++ /dev/null
@@ -1,245 +0,0 @@
-#include <erl_nif.h>
-#include <string.h>
-#include <stdio.h>
-
-static ERL_NIF_TERM atom_xmlelement;
-static ERL_NIF_TERM atom_xmlcdata;
-
-struct buf {
-  int limit;
-  int len;
-  unsigned char *b;
-};
-
-static int make_element(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM el);
-
-static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
-{
-  atom_xmlelement = enif_make_atom(env, "xmlel");
-  atom_xmlcdata = enif_make_atom(env, "xmlcdata");
-  return 0;
-}
-
-static struct buf *init_buf(ErlNifEnv* env)
-{
-  struct buf *rbuf = enif_alloc(sizeof(struct buf));
-  rbuf->limit = 1024;
-  rbuf->len = 0;
-  rbuf->b = enif_alloc(rbuf->limit);
-  return rbuf;
-}
-
-static void destroy_buf(ErlNifEnv* env, struct buf *rbuf)
-{
-  if (rbuf) {
-    if (rbuf->b) {
-      enif_free(rbuf->b);
-    };
-    enif_free(rbuf);
-  };
-}
-
-inline void resize_buf(ErlNifEnv* env, struct buf *rbuf, int len_to_add)
-{
-  int new_len = rbuf->len + len_to_add;
-  
-  if (new_len > rbuf->limit) {
-     while (new_len > rbuf->limit)
-       rbuf->limit *= 2;
-     rbuf->b = enif_realloc(rbuf->b, rbuf->limit);
-  }
-}
-
-static void buf_add_char(ErlNifEnv* env, struct buf *rbuf, unsigned char c)
-{
-  resize_buf(env, rbuf, 1);
-  (rbuf->b)[rbuf->len] = c;
-  rbuf->len += 1;
-}
-
-static void buf_add_str(ErlNifEnv* env, struct buf *rbuf, char *data, int len)
-{
-  resize_buf(env, rbuf, len);
-  memcpy(rbuf->b + rbuf->len, data, len);
-  rbuf->len += len;
-}
-
-inline void crypt(ErlNifEnv* env, struct buf *rbuf, unsigned char *data, int len)
-{
-  int i;
-
-  for (i = 0; i < len; i++) {
-    switch (data[i]) {
-    case '&':
-      buf_add_str(env, rbuf, "&amp;", 5);
-      break;
-    case '<':
-      buf_add_str(env, rbuf, "&lt;", 4);
-      break;
-    case '>':
-      buf_add_str(env, rbuf, "&gt;", 4);
-      break;
-    case '"':
-      buf_add_str(env, rbuf, "&quot;", 6);
-      break;
-    case '\'':
-      buf_add_str(env, rbuf, "&apos;", 6);
-      break;
-    default:
-      buf_add_char(env, rbuf, data[i]);
-      break;
-    };
-  };
-}
-
-static int make_elements(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM els)
-{
-  ERL_NIF_TERM head, tail;
-  int ret = 0;
-
-  while (enif_get_list_cell(env, els, &head, &tail)) {
-    ret = make_element(env, rbuf, head);
-    if (ret) {
-      els = tail;
-    } else {
-      break;
-    };
-  };
-
-  return ret;
-}
-
-static int make_attrs(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM attrs)
-{
-  ErlNifBinary name, data;
-  ERL_NIF_TERM head, tail;
-  const ERL_NIF_TERM *tuple;
-  int arity, ret = 1;
-  
-  while (enif_get_list_cell(env, attrs, &head, &tail)) {
-    if (enif_get_tuple(env, head, &arity, &tuple)) {
-      if (arity == 2) {
-       if (enif_inspect_iolist_as_binary(env, tuple[0], &name) &&
-           enif_inspect_iolist_as_binary(env, tuple[1], &data)) {
-         buf_add_char(env, rbuf, ' ');
-         buf_add_str(env, rbuf, (char *)name.data, name.size);
-         buf_add_str(env, rbuf, "='", 2);
-         crypt(env, rbuf, data.data, data.size);
-         buf_add_char(env, rbuf, '\'');
-         attrs = tail;
-       } else {
-         ret = 0;
-         break;
-       };
-      } else {
-       ret = 0;
-       break;
-      };
-    } else {
-      ret = 0;
-      break;
-    };
-  };
-  
-  return ret;
-}
-
-static int make_element(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM el)
-{
-  ErlNifBinary cdata, name;
-  const ERL_NIF_TERM *tuple;
-  int arity, ret = 0;
-
-  if (enif_get_tuple(env, el, &arity, &tuple)) {
-    if (arity == 2) {
-      if (!enif_compare(tuple[0], atom_xmlcdata)) {
-       if (enif_inspect_iolist_as_binary(env, tuple[1], &cdata)) {
-         crypt(env, rbuf, cdata.data, cdata.size);
-         ret = 1;
-       };
-      };
-    };
-    if (arity == 4) {
-      if (!enif_compare(tuple[0], atom_xmlelement)) {
-       if (enif_inspect_iolist_as_binary(env, tuple[1], &name)) {
-         buf_add_char(env, rbuf, '<');
-         buf_add_str(env, rbuf, (char *)name.data, name.size);
-         ret = make_attrs(env, rbuf, tuple[2]);
-         if (ret) {
-           if (enif_is_empty_list(env, tuple[3])) {
-             buf_add_str(env, rbuf, "/>", 2);
-           } else {
-             buf_add_char(env, rbuf, '>');
-             ret = make_elements(env, rbuf, tuple[3]);
-             if (ret) {
-               buf_add_str(env, rbuf, "</", 2);
-               buf_add_str(env, rbuf, (char*)name.data, name.size);
-               buf_add_char(env, rbuf, '>');
-             };
-           };
-         };
-       };
-      };
-    };
-  };
-  
-  return ret;
-}
-
-static ERL_NIF_TERM element_to(ErlNifEnv* env, int argc,
-                              const ERL_NIF_TERM argv[],
-                              int as_string)
-{
-  ErlNifBinary output;
-  ERL_NIF_TERM result;
-  struct buf *rbuf;
-
-  if (argc == 1) {
-    rbuf = init_buf(env);
-    if (make_element(env, rbuf, argv[0])) {
-      if (as_string) {
-       (rbuf->b)[rbuf->len] = 0;
-       result = enif_make_string(env, (char *) rbuf->b, ERL_NIF_LATIN1);
-       destroy_buf(env, rbuf);
-       return result;
-      }        else {
-       if (enif_alloc_binary(rbuf->len, &output)) {
-         memcpy(output.data, rbuf->b, rbuf->len);
-         result = enif_make_binary(env, &output);
-         destroy_buf(env, rbuf);
-         return result;
-       };
-      };
-    };
-    destroy_buf(env, rbuf);
-  };
-  
-  return enif_make_badarg(env);
-}
-
-#ifdef SSL40
-static ERL_NIF_TERM element_to_string(ErlNifEnv* env, int argc,
-                                     const ERL_NIF_TERM argv[])
-{
-  return element_to(env, argc, argv, 1);
-}
-#endif
-
-static ERL_NIF_TERM element_to_binary(ErlNifEnv* env, int argc,
-                                     const ERL_NIF_TERM argv[])
-{
-  return element_to(env, argc, argv, 0);
-}
-
-static ErlNifFunc nif_funcs[] =
-  {
-    /* Stupid Erlang bug with enif_make_string() is fixed
-       in R14A only (OTP-8685), so we can't use
-       element_to_string in Erlang < R14A.*/
-#ifdef SSL40
-    {"element_to_string", 1, element_to_string},
-#endif
-    {"element_to_binary", 1, element_to_binary}
-  };
-
-ERL_NIF_INIT(xml, nif_funcs, load, NULL, NULL, NULL)
diff --git a/src/xml.erl b/src/xml.erl
deleted file mode 100644 (file)
index 7cd3acd..0000000
+++ /dev/null
@@ -1,442 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : xml.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : XML utils
-%%% Created : 20 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(xml).
-
--author('alexey@process-one.net').
-
--export([element_to_binary/1,
-        crypt/1, make_text_node/1, remove_cdata/1,
-        remove_subtags/3, get_cdata/1, get_tag_cdata/1,
-        get_attr/2, get_attr_s/2, get_tag_attr/2,
-        get_tag_attr_s/2, get_subtag/2, get_subtag_cdata/2,
-        append_subtags/2, get_path_s/2, start/0,
-        replace_tag_attr/3, to_xmlel/1]).
-
--include("jlib.hrl").
--include("ejabberd.hrl").
-
-%% Select at compile time how to escape characters in binary text
-%% nodes.
-%% Can be choosen with ./configure --enable-full-xml
--ifdef(FULL_XML_SUPPORT).
-
--define(ESCAPE_BINARY(CData), make_text_node(CData)).
-
--else.
-
--define(ESCAPE_BINARY(CData), crypt(CData)).
-
--endif.
-
-%% Replace element_to_binary/1 with NIF
-%% Can be choosen with ./configure --enable-nif
--ifdef(NIF).
-
-start() ->
-    SOPath = filename:join(ejabberd:get_so_path(), "xml"),
-    case catch erlang:load_nif(SOPath, 0) of
-      ok -> ok;
-      Err -> ?WARNING_MSG("unable to load xml NIF: ~p", [Err])
-    end.
-
--else.
-
-start() -> ok.
-
--endif.
-
-%%
--spec(element_to_binary/1 ::
-(
-  El :: xmlel() | cdata())
-    -> binary()
-).
-
-element_to_binary(El) ->
-    iolist_to_binary(element_to_string(El)).
-
-%%
--spec(element_to_string/1 ::
-(
-  El :: xmlel() | cdata())
-    -> string()
-).
-
-element_to_string(El) ->
-    case catch element_to_string_nocatch(El) of
-      {'EXIT', Reason} -> erlang:error({badxml, El, Reason});
-      Result -> Result
-    end.
-
--spec(element_to_string_nocatch/1 ::
-(
-  El :: xmlel() | cdata())
-    -> iolist()
-).
-
-element_to_string_nocatch(El) ->
-    case El of
-      #xmlel{name = Name, attrs = Attrs, children = Els} ->
-         if Els /= [] ->
-                [$<, Name, attrs_to_list(Attrs), $>,
-                 [element_to_string_nocatch(E) || E <- Els], $<, $/,
-                 Name, $>];
-            true -> [$<, Name, attrs_to_list(Attrs), $/, $>]
-         end;
-      %% We do not crypt CDATA binary, but we enclose it in XML CDATA
-      {xmlcdata, CData} ->
-         ?ESCAPE_BINARY(CData)
-    end.
-
-attrs_to_list(Attrs) -> [attr_to_list(A) || A <- Attrs].
-
-attr_to_list({Name, Value}) ->
-    [$\s, Name, $=, $', crypt(Value), $'].
-
-%% Make a cdata_binary depending on what characters it contains
-crypt(S) ->
-    << <<(case C of
-              $& -> <<"&amp;">>;
-              $< -> <<"&lt;">>;
-              $> -> <<"&gt;">>;
-              $" -> <<"&quot;">>;
-              $' -> <<"&apos;">>;
-              _ -> <<C>>
-          end)/binary>>
-       || <<C>> <= S >>.
-
-%%
--spec(make_text_node/1 ::
-(
-  CData :: binary())
-    -> binary()
-).
-
-make_text_node(CData) ->
-    case cdata_need_escape(CData) of
-      cdata ->
-         CDATA1 = <<"<![CDATA[">>,
-         CDATA2 = <<"]]>">>,
-         iolist_to_binary([CDATA1, CData, CDATA2]);
-      none -> CData;
-      {cdata, EndTokens} ->
-         EscapedCData = escape_cdata(CData, EndTokens),
-         iolist_to_binary(EscapedCData)
-    end.
-
-%% Returns escape type needed for the text node
-%% none, cdata, {cdata, [Positions]}
-%% Positions is a list a integer containing positions of CDATA end
-%% tokens, so that they can be escaped
-cdata_need_escape(CData) ->
-    cdata_need_escape(CData, 0, false, []).
-
-cdata_need_escape(<<>>, _, false, _) -> none;
-cdata_need_escape(<<>>, _, true, []) -> cdata;
-cdata_need_escape(<<>>, _, true, CDataEndTokens) ->
-    {cdata, lists:reverse(CDataEndTokens)};
-cdata_need_escape(<<$], $], $>, Rest/binary>>,
-                 CurrentPosition, _XMLEscape, CDataEndTokens) ->
-    NewPosition = CurrentPosition + 3,
-    cdata_need_escape(Rest, NewPosition, true,
-                     [CurrentPosition + 1 | CDataEndTokens]);
-%% Only <, & need to be escaped in XML text node
-%% See reference: http://www.w3.org/TR/xml11/#syntax
-cdata_need_escape(<<$<, Rest/binary>>, CurrentPosition,
-                 _XMLEscape, CDataEndTokens) ->
-    cdata_need_escape(Rest, CurrentPosition + 1, true,
-                     CDataEndTokens);
-cdata_need_escape(<<$&, Rest/binary>>, CurrentPosition,
-                 _XMLEscape, CDataEndTokens) ->
-    cdata_need_escape(Rest, CurrentPosition + 1, true,
-                     CDataEndTokens);
-cdata_need_escape(<<_:8, Rest/binary>>, CurrentPosition,
-                 XMLEscape, CDataEndTokens) ->
-%% escape cdata that contain CDATA end tokens
-%% EndTokens is a list of position of end tokens (integer)
-%% This is supposed to be a very rare case: You need to generate several
-%% fields, splitting it in the middle of the end token.
-%% See example: http://en.wikipedia.org/wiki/CDATA#Uses_of_CDATA_sections
-    cdata_need_escape(Rest, CurrentPosition + 1, XMLEscape,
-                     CDataEndTokens).
-
-escape_cdata(CData, EndTokens) ->
-    escape_cdata(CData, 0, EndTokens, []).
-
-escape_cdata(<<>>, _CurrentPosition, [], Acc) ->
-    lists:reverse(Acc);
-escape_cdata(Rest, CurrentPosition, [], Acc) ->
-    CDATA1 = <<"<![CDATA[">>,
-    CDATA2 = <<"]]>">>,
-    escape_cdata(<<>>, CurrentPosition, [],
-                [CDATA2, Rest, CDATA1 | Acc]);
-escape_cdata(CData, Index, [Pos | Positions], Acc) ->
-    CDATA1 = <<"<![CDATA[">>,
-    CDATA2 = <<"]]>">>,
-    Split = Pos - Index,
-    {Part, Rest} = split_binary(CData, Split + 1),
-    escape_cdata(Rest, Pos + 1, Positions,
-                [CDATA2, Part, CDATA1 | Acc]).
-
-%%
--spec(remove_cdata_p/1 ::
-(
-  El :: xmlel() | cdata())
-    -> boolean()
-).
-
-remove_cdata_p(#xmlel{}) -> true;
-remove_cdata_p(_) -> false.
-
-%%
--spec(remove_cdata/1 ::
-(
-  L :: [xmlel() | cdata()])
-    -> [xmlel()]
-).
-
-remove_cdata(L) -> [E || E <- L, remove_cdata_p(E)].
-
--spec(remove_subtags/3 ::
-(
-  Xmlel :: xmlel(),
-  Name  :: binary(),
-  Attr  :: attr())
-    -> Xmlel :: xmlel()
-).
-
-remove_subtags(#xmlel{name = TagName, attrs = TagAttrs, children = Els},
-  Name, Attr) ->
-    #xmlel{name = TagName, attrs = TagAttrs,
-        children = remove_subtags1(Els, [], Name, Attr)}.
-
-%%
--spec(remove_subtags1/4 ::
-(
-  Els    :: [xmlel() | cdata()],
-  NewEls :: [xmlel()],
-  Name   :: binary(),
-  Attr   :: attr())
-    -> NewEls :: [xmlel()]
-).
-
-remove_subtags1([], NewEls, _Name, _Attr) ->
-    lists:reverse(NewEls);
-remove_subtags1([El | Els], NewEls, Name,
-               {AttrName, AttrValue} = Attr) ->
-    case El of
-      #xmlel{name = Name, attrs = Attrs} ->
-         case get_attr(AttrName, Attrs) of
-           false ->
-               remove_subtags1(Els, [El | NewEls], Name, Attr);
-           {value, AttrValue} ->
-               remove_subtags1(Els, NewEls, Name, Attr);
-           _ -> remove_subtags1(Els, [El | NewEls], Name, Attr)
-         end;
-      _ -> remove_subtags1(Els, [El | NewEls], Name, Attr)
-    end.
-
--spec(get_cdata/1 ::
-(
-  L :: [xmlel() | cdata()])
-    -> binary()
-).
-
-get_cdata(L) ->
-    (iolist_to_binary(get_cdata(L, <<"">>))).
-
--spec(get_cdata/2 ::
-(
-  L :: [xmlel() | cdata()],
-  S :: binary() | iolist())
-    -> binary() | iolist()
-).
-
-get_cdata([{xmlcdata, CData} | L], S) ->
-     get_cdata(L, [S, CData]);
-get_cdata([_ | L], S) -> get_cdata(L, S);
-get_cdata([], S) -> S.
-
--spec(get_tag_cdata/1 ::
-(
-  Xmlel :: xmlel())
-    -> binary()
-).
-
-get_tag_cdata(#xmlel{children = Els}) -> get_cdata(Els).
-
-%%
--spec(get_attr/2 ::
-(
-  AttrName :: binary(),
-  Attrs    :: [attr()])
-    -> {value, binary()}
-     | false
-).
-
-get_attr(AttrName, Attrs) ->
-    case lists:keysearch(AttrName, 1, Attrs) of
-      {value, {_, Val}} -> {value, Val};
-      _ -> false
-    end.
-
-%%
--spec(get_attr_s/2 ::
-(
-  AttrName :: binary(),
-  Attrs    :: [attr()])
-    -> Val :: binary()
-).
-
-get_attr_s(AttrName, Attrs) ->
-    case lists:keysearch(AttrName, 1, Attrs) of
-      {value, {_, Val}} -> Val;
-      _ -> <<"">>
-    end.
-
-%%
--spec(get_tag_attr/2 ::
-(
-  AttrName :: binary(),
-  Xmlel    :: xmlel())
-    -> {value, binary()}
-     | false
-).
-
-get_tag_attr(AttrName, #xmlel{attrs = Attrs}) ->
-    get_attr(AttrName, Attrs).
-
-%%
--spec(get_tag_attr_s/2 ::
-(
-  AttrName :: binary(),
-  Xmlel    :: xmlel())
-    -> binary()
-).
-
-get_tag_attr_s(AttrName, #xmlel{attrs = Attrs}) ->
-    get_attr_s(AttrName, Attrs).
-
-%%
--spec(get_subtag/2 ::
-(
-  Xmlel :: xmlel(),
-  Name  :: binary())
-    -> xmlel() | false
-).
-
-get_subtag(#xmlel{children = Els}, Name) ->
-    get_subtag1(Els, Name).
-
-%%
--spec(get_subtag1/2 ::
-(
-  Els  :: [xmlel() | cdata()],
-  Name :: binary())
-    -> xmlel() | false
-).
-
-get_subtag1([El | Els], Name) ->
-    case El of
-      #xmlel{name = Name} -> El;
-      _ -> get_subtag1(Els, Name)
-    end;
-get_subtag1([], _) -> false.
-
-%%
--spec(get_subtag_cdata/2 ::
-(
-  Tag  :: xmlel(),
-  Name :: binary())
-    -> binary()
-).
-
-get_subtag_cdata(Tag, Name) ->
-    case get_subtag(Tag, Name) of
-      false -> <<"">>;
-      Subtag -> get_tag_cdata(Subtag)
-    end.
-
-%%
--spec(append_subtags/2 ::
-(
-  Xmlel    :: xmlel(),
-  SubTags2 :: [xmlel() | cdata()])
-    -> Xmlel :: xmlel()
-).
-
-append_subtags(#xmlel{name = Name, attrs = Attrs, children = SubTags1}, SubTags2) ->
-    #xmlel{name = Name, attrs = Attrs, children = SubTags1 ++ SubTags2}.
-
-%%
--spec(get_path_s/2 ::
-(
-  El   :: xmlel(),
-  Path :: [{elem, Name::binary()}
-          |{attr, Name::binary()}
-          |cdata])
-    -> xmlel()
-     | binary()
-).
-
-get_path_s(El, []) -> El;
-get_path_s(El, [{elem, Name} | Path]) ->
-    case get_subtag(El, Name) of
-      false -> <<"">>;
-      SubEl -> get_path_s(SubEl, Path)
-    end;
-get_path_s(El, [{attr, Name}]) ->
-    get_tag_attr_s(Name, El);
-get_path_s(El, [cdata]) -> get_tag_cdata(El).
-
-%%
--spec(replace_tag_attr/3 ::
-(
-  Name  :: binary(),
-  Value :: binary(),
-  Xmlel :: xmlel())
-    -> Xmlel :: #xmlel{
-           name     :: binary(),
-           attrs    :: [attr(),...],
-           children :: [xmlel() | cdata()]
-       }
-).
-
-replace_tag_attr(Name, Value, Xmlel) ->
-    Xmlel#xmlel{
-        attrs = [{Name, Value} | lists:keydelete(Name, 1, Xmlel#xmlel.attrs)]
-    }.
-
--spec to_xmlel(xmlelement() | xmlel()) -> xmlel().
-
-to_xmlel({_, Name, Attrs, Els}) ->
-    #xmlel{name = iolist_to_binary(Name),
-           attrs = [{iolist_to_binary(K), iolist_to_binary(V)}
-                    || {K, V} <- Attrs],
-           children = [to_xmlel(El) || El <- Els]};
-to_xmlel({xmlcdata, CData}) ->
-    {xmlcdata, iolist_to_binary(CData)}.
diff --git a/src/xml_stream.erl b/src/xml_stream.erl
deleted file mode 100644 (file)
index 17244af..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-%%%----------------------------------------------------------------------
-%%% File    : xml_stream.erl
-%%% Author  : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : Parse XML streams
-%%% Created : 17 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
-%%%
-%%%
-%%% ejabberd, Copyright (C) 2002-2013   ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License
-%%% along with this program; if not, write to the Free Software
-%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-%%% 02111-1307 USA
-%%%
-%%%----------------------------------------------------------------------
-
--module(xml_stream).
-
--author('alexey@process-one.net').
-
--export([new/1, new/2, parse/2, close/1,
-        parse_element/1]).
-
--define(XML_START, 0).
-
--define(XML_END, 1).
-
--define(XML_CDATA, 2).
-
--define(XML_ERROR, 3).
-
--define(PARSE_COMMAND, 0).
-
--define(PARSE_FINAL_COMMAND, 1).
-
--record(xml_stream_state,
-       {callback_pid = self() :: pid(),
-         port                  :: port(),
-         stack = []            :: stack(),
-         size = 0              :: non_neg_integer(),
-         maxsize = infinity    :: non_neg_integer() | infinity}).
-
--type xml_stream_el() :: {xmlstreamraw, binary()} |
-                         {xmlstreamcdata, binary()} |
-                         {xmlstreamelement, xmlel()} |
-                         {xmlstreamend, binary()} |
-                         {xmlstreamstart, binary(), [attr()]} |
-                         {xmlstreamerror, binary()}.
-
--type xml_stream_state() :: #xml_stream_state{}.
--type stack() :: [xmlel()].
--type event() :: {?XML_START, {binary(), [attr()]}} |
-                 {?XML_END, binary()} |
-                 {?XML_CDATA, binary()} |
-                 {?XML_ERROR, binary()}.
-
--export_type([xml_stream_state/0, xml_stream_el/0]).
-
--include("jlib.hrl").
-
-process_data(CallbackPid, Stack, Data) ->
-    case Data of
-       {?XML_START, {Name, Attrs}} ->
-           if
-               Stack == [] ->
-                   catch gen_fsm:send_event(CallbackPid,
-                                            {xmlstreamstart, Name, Attrs}),
-                   %% There is no need to store name or attributes of
-                   %% stream opening element as it is not used
-                   %% anymore.
-                   [xmlstreamstart];
-               true ->
-                   [#xmlel{name = Name, attrs = Attrs, children = []} | Stack]
-           end;
-       {?XML_END, EndName} ->
-           case Stack of
-               [xmlstreamstart] ->
-                   catch gen_fsm:send_event(CallbackPid,
-                                            {xmlstreamend, EndName}),
-                   [];
-               [#xmlel{name = Name, attrs = Attrs, children = Els}, xmlstreamstart] ->
-                   NewEl = #xmlel{name = Name, attrs = Attrs, children = lists:reverse(Els)},
-                   catch gen_fsm:send_event(CallbackPid,
-                                            {xmlstreamelement, NewEl}),
-                   [xmlstreamstart];
-               [#xmlel{name = Name, attrs = Attrs, children = Els},
-                #xmlel{name = Name1, attrs = Attrs1, children = Els1} | Tail] ->
-                   NewEl = #xmlel{name = Name, attrs = Attrs, children = lists:reverse(Els)},
-                   [#xmlel{name = Name1, attrs = Attrs1, children = [NewEl | Els1]} | Tail]
-           end;
-       {?XML_CDATA, CData} ->
-           case Stack of
-               [xmlstreamstart] ->
-                   [xmlstreamstart];
-               %% Merge CDATA nodes if they are contiguous
-               %% This does not change the semantic: the split in
-               %% several CDATA nodes depends on the TCP/IP packet
-               %% fragmentation
-               [#xmlel{name = Name, attrs = Attrs,
-                       children = [{xmlcdata, PreviousCData} | Els]}
-               | Tail] ->
-                   [#xmlel{name = Name, attrs = Attrs,
-                           children =
-                               [{xmlcdata,
-                               iolist_to_binary([PreviousCData, CData])}
-                               | Els]}
-                   | Tail];
-               %% No previous CDATA
-               [#xmlel{name = Name, attrs = Attrs, children = Els}
-               | Tail] ->
-                   [#xmlel{name = Name, attrs = Attrs,
-                           children = [{xmlcdata, CData} | Els]}
-                   | Tail];
-               [] -> []
-           end;
-       {?XML_ERROR, Err} ->
-           catch gen_fsm:send_event(CallbackPid, {xmlstreamerror, Err})
-    end.
-
--spec new(pid()) -> xml_stream_state().
-
-new(CallbackPid) -> new(CallbackPid, infinity).
-
--spec new(pid(), non_neg_integer() | infinity) -> xml_stream_state().
-
-new(CallbackPid, MaxSize) ->
-    Port = open_port({spawn, "expat_erl"}, [binary]),
-    #xml_stream_state{callback_pid = CallbackPid,
-                     port = Port, stack = [], size = 0, maxsize = MaxSize}.
-
--spec parse(xml_stream_state(), iodata()) -> xml_stream_state().
-
-parse(#xml_stream_state{callback_pid = CallbackPid,
-                       port = Port, stack = Stack, size = Size,
-                       maxsize = MaxSize} =
-         State,
-      Str) ->
-    StrSize = byte_size(Str),
-    Res = port_control(Port, ?PARSE_COMMAND, Str),
-    {NewStack, NewSize} = lists:foldl(fun (Data,
-                                          {St, Sz}) ->
-                                             NewSt = process_data(CallbackPid,
-                                                                  St, Data),
-                                             case NewSt of
-                                               [_] -> {NewSt, 0};
-                                               _ -> {NewSt, Sz}
-                                             end
-                                     end,
-                                     {Stack, Size + StrSize},
-                                     binary_to_term(Res)),
-    if NewSize > MaxSize ->
-          catch gen_fsm:send_event(CallbackPid,
-                                   {xmlstreamerror,
-                                    <<"XML stanza is too big">>});
-       true -> ok
-    end,
-    State#xml_stream_state{stack = NewStack,
-                          size = NewSize}.
-
--spec close(xml_stream_state()) -> true.
-
-close(#xml_stream_state{port = Port}) ->
-    port_close(Port).
-
--spec parse_element(iodata()) -> xmlel() |
-                                 {error, parse_error} |
-                                 {error, binary()}.
-
-parse_element(Str) ->
-    Port = open_port({spawn, "expat_erl"}, [binary]),
-    Res = port_control(Port, ?PARSE_FINAL_COMMAND, Str),
-    port_close(Port),
-    process_element_events(binary_to_term(Res)).
-
-process_element_events(Events) ->
-    process_element_events(Events, []).
-
--spec process_element_events([event()], stack()) -> xmlel() |
-                                                    {error, parse_error} |
-                                                    {error, binary()}.
-
-process_element_events([], _Stack) ->
-    {error, parse_error};
-process_element_events([Event | Events], Stack) ->
-    case Event of
-      {?XML_START, {Name, Attrs}} ->
-         process_element_events(Events,
-                                [#xmlel{name = Name, attrs = Attrs,
-                                        children = []}
-                                 | Stack]);
-      {?XML_END, _EndName} ->
-         case Stack of
-           [#xmlel{name = Name, attrs = Attrs, children = Els}
-            | Tail] ->
-               NewEl = #xmlel{name = Name, attrs = Attrs,
-                              children = lists:reverse(Els)},
-               case Tail of
-                 [] ->
-                     if Events == [] -> NewEl;
-                        true -> {error, parse_error}
-                     end;
-                 [#xmlel{name = Name1, attrs = Attrs1, children = Els1}
-                  | Tail1] ->
-                     process_element_events(Events,
-                                            [#xmlel{name = Name1,
-                                                    attrs = Attrs1,
-                                                    children = [NewEl | Els1]}
-                                             | Tail1])
-               end
-         end;
-      {?XML_CDATA, CData} ->
-         case Stack of
-           [#xmlel{name = Name, attrs = Attrs, children = Els}
-            | Tail] ->
-               process_element_events(Events,
-                                      [#xmlel{name = Name, attrs = Attrs,
-                                              children =
-                                                  [{xmlcdata, CData} | Els]}
-                                       | Tail]);
-           [] -> process_element_events(Events, [])
-         end;
-      {?XML_ERROR, Err} -> {error, Err}
-    end.
diff --git a/test/ejabberd_SUITE.erl b/test/ejabberd_SUITE.erl
new file mode 100644 (file)
index 0000000..0d66596
--- /dev/null
@@ -0,0 +1,638 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2013, Evgeniy Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created :  2 Jun 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+-module(ejabberd_SUITE).
+
+-compile(export_all).
+
+-include_lib("common_test/include/ct.hrl").
+-include("ns.hrl").
+-include("ejabberd.hrl").
+-include("xmpp_codec.hrl").
+
+-define(STREAM_HEADER,
+       <<"<?xml version='1.0'?><stream:stream "
+         "xmlns:stream='http://etherx.jabber.org/stream"
+         "s' xmlns='jabber:client' to='~s' version='1.0"
+         "'>">>).
+
+-define(STREAM_TRAILER, <<"</stream:stream>">>).
+
+-define(PUBSUB(Node), <<(?NS_PUBSUB)/binary, "#", Node>>).
+
+suite() ->
+    [{timetrap,{seconds,30}}].
+
+init_per_suite(Config) ->
+    DataDir = proplists:get_value(data_dir, Config),
+    PrivDir = proplists:get_value(priv_dir, Config),
+    ConfigPath = filename:join([DataDir, "ejabberd.cfg"]),
+    LogPath = filename:join([PrivDir, "ejabberd.log"]),
+    SASLPath = filename:join([PrivDir, "sasl.log"]),
+    MnesiaDir = filename:join([PrivDir, "mnesia"]),
+    application:set_env(ejabberd, config, ConfigPath),
+    application:set_env(ejabberd, log_path, LogPath),
+    application:set_env(sasl, sasl_error_logger, {file, SASLPath}),
+    application:set_env(mnesia, dir, MnesiaDir),
+    [{server, <<"localhost">>},
+     {port, 5222},
+     {user, <<"test_suite">>},
+     {password, <<"pass">>}
+     |Config].
+
+end_per_suite(_Config) ->
+    ok.
+
+init_per_group(_GroupName, Config) ->
+    Config.
+
+end_per_group(_GroupName, _Config) ->
+    ok.
+
+init_per_testcase(start_ejabberd, Config) ->
+    Config;
+init_per_testcase(TestCase, OrigConfig) ->
+    Resource = list_to_binary(atom_to_list(TestCase)),
+    Config = [{resource, Resource}|OrigConfig],
+    case TestCase of
+        test_connect ->
+            Config;
+        test_auth ->
+            connect(Config);
+        auth_md5 ->
+            connect(Config);
+        auth_plain ->
+            connect(Config);
+        test_bind ->
+            auth(connect(Config));
+        test_open_session ->
+            bind(auth(connect(Config)));
+        _ ->
+            open_session(bind(auth(connect(Config))))
+    end.
+
+end_per_testcase(_TestCase, _Config) ->
+    ok.
+
+groups() ->
+    [].
+
+%%all() -> [start_ejabberd, pubsub].
+
+all() ->
+    [start_ejabberd,
+     test_connect,
+     auth_plain,
+     auth_md5,
+     test_auth,
+     test_bind,
+     test_open_session,
+     roster_get,
+     presence_broadcast,
+     ping,
+     version,
+     time,
+     stats,
+     disco,
+     last,
+     private,
+     privacy,
+     blocking,
+     vcard,
+     pubsub,
+     stop_ejabberd].
+
+start_ejabberd(Config) ->
+    ok = application:start(ejabberd),
+    ok = re_register(Config),
+    Config.
+
+stop_ejabberd(Config) ->
+    ok = application:stop(ejabberd),
+    #stream_error{reason = 'system-shutdown'} = recv(),
+    {xmlstreamend, <<"stream:stream">>} = recv(),
+    Config.
+
+test_connect(Config) ->
+    disconnect(connect(Config)).
+
+connect(Config) ->
+    {ok, Sock} = ejabberd_socket:connect(
+                   binary_to_list(?config(server, Config)),
+                   ?config(port, Config),
+                   [binary, {packet, 0}, {active, false}]),
+    Config1 = [{socket, Sock}|Config],
+    ok = send_text(Config1, io_lib:format(?STREAM_HEADER,
+                                          [?config(server, Config1)])),
+    {xmlstreamstart, <<"stream:stream">>, Attrs} = recv(),
+    <<"jabber:client">> = xml:get_attr_s(<<"xmlns">>, Attrs),
+    <<"1.0">> = xml:get_attr_s(<<"version">>, Attrs),
+    #stream_features{sub_els = Fs} = recv(),
+    Mechs = lists:flatmap(
+              fun(#sasl_mechanisms{mechanism = Ms}) ->
+                      Ms;
+                 (_) ->
+                      []
+              end, Fs),
+    [{mechs, Mechs}|Config1].
+
+disconnect(Config) ->
+    Socket = ?config(socket, Config),
+    ok = ejabberd_socket:send(Socket, ?STREAM_TRAILER),
+    {xmlstreamend, <<"stream:stream">>} = recv(),
+    ejabberd_socket:close(Socket),
+    Config.
+
+test_auth(Config) ->
+    disconnect(auth(Config)).
+
+auth(Config) ->
+    Mechs = ?config(mechs, Config),
+    HaveMD5 = lists:member(<<"DIGEST-MD5">>, Mechs),
+    HavePLAIN = lists:member(<<"PLAIN">>, Mechs),
+    if HavePLAIN ->
+            auth_SASL(<<"PLAIN">>, Config);
+       HaveMD5 ->
+            auth_SASL(<<"DIGEST-MD5">>, Config);
+       true ->
+            ct:fail(no_sasl_mechanisms_available)
+    end.
+
+test_bind(Config) ->
+    disconnect(bind(Config)).
+
+bind(Config) ->
+    ID = send(Config,
+              #iq{type = set,
+                  sub_els = [#bind{resource = ?config(resource, Config)}]}),
+    #iq{type = result, id = ID, sub_els = [#bind{}]} = recv(),
+    Config.
+
+test_open_session(Config) ->
+    disconnect(open_session(Config)).
+
+open_session(Config) ->
+    ID = send(Config, #iq{type = set, sub_els = [#session{}]}),
+    #iq{type = result, id = ID, sub_els = SubEls} = recv(),
+    case SubEls of
+        [] ->
+            ok;
+        [#session{}] ->
+            %% BUG: we should not receive this!
+            %% TODO: should be fixed in ejabberd
+            ok
+    end,
+    Config.
+
+roster_get(Config) ->
+    ID = send(Config, #iq{type = get, sub_els = [#roster{}]}),
+    #iq{type = result, id = ID,
+          sub_els = [#roster{item = []}]} = recv(),
+    disconnect(Config).
+
+presence_broadcast(Config) ->
+    send(Config, #presence{}),
+    JID = my_jid(Config),
+    #presence{from = JID, to = JID} = recv(),
+    disconnect(Config).
+
+ping(Config) ->
+    true = is_feature_advertised(Config, ?NS_PING),
+    ID = send(Config,
+              #iq{type = get, sub_els = [#ping{}], to = server_jid(Config)}),
+    #iq{type = result, id = ID, sub_els = []} = recv(),
+    disconnect(Config).
+
+version(Config) ->
+    true = is_feature_advertised(Config, ?NS_VERSION),
+    ID = send(Config, #iq{type = get, sub_els = [#version{}],
+                          to = server_jid(Config)}),
+    #iq{type = result, id = ID, sub_els = [#version{}]} = recv(),
+    disconnect(Config).
+
+time(Config) ->
+    true = is_feature_advertised(Config, ?NS_TIME),
+    ID = send(Config, #iq{type = get, sub_els = [#time{}],
+                          to = server_jid(Config)}),
+    #iq{type = result, id = ID, sub_els = [#time{}]} = recv(),
+    disconnect(Config).
+
+disco(Config) ->
+    true = is_feature_advertised(Config, ?NS_DISCO_INFO),
+    true = is_feature_advertised(Config, ?NS_DISCO_ITEMS),
+    I1 = send(Config, #iq{type = get, sub_els = [#disco_items{}],
+                          to = server_jid(Config)}),
+    #iq{type = result, id = I1, sub_els = [#disco_items{items = Items}]} = recv(),
+    lists:foreach(
+      fun(#disco_item{jid = JID, node = Node}) ->
+              I = send(Config,
+                       #iq{type = get, to = JID,
+                           sub_els = [#disco_info{node = Node}]}),
+              #iq{type = result, id = I, sub_els = _} = recv()
+      end, Items),
+    disconnect(Config).
+
+private(Config) ->
+    I1 = send(Config, #iq{type = get, sub_els = [#private{}],
+                          to = server_jid(Config)}),
+    #iq{type = error, id = I1} = recv(),
+    Conference = #bookmark_conference{name = <<"Some name">>,
+                                      autojoin = true,
+                                      jid = jlib:make_jid(
+                                              <<"some">>,
+                                              <<"some.conference.org">>,
+                                              <<>>)},
+    Storage = #bookmark_storage{conference = [Conference]},
+    I2 = send(Config, #iq{type = set,
+                          sub_els = [#private{sub_els = [Storage]}]}),
+    #iq{type = result, id = I2, sub_els = []} = recv(),
+    I3 = send(Config,
+              #iq{type = get,
+                  sub_els = [#private{sub_els = [#bookmark_storage{}]}]}),
+    #iq{type = result, id = I3,
+        sub_els = [#private{sub_els = [Storage]}]} = recv(),
+    disconnect(Config).
+
+last(Config) ->
+    true = is_feature_advertised(Config, ?NS_LAST),
+    ID = send(Config, #iq{type = get, sub_els = [#last{}],
+                          to = server_jid(Config)}),
+    #iq{type = result, id = ID, sub_els = [#last{}]} = recv(),
+    disconnect(Config).
+
+privacy(Config) ->
+    %% BUG: the feature MUST be advertised via disco#info:
+    %%      http://xmpp.org/extensions/xep-0016.html#disco
+    %% It seems like this bug exists because Privacy Lists
+    %% were implemented according to the old RFC where support
+    %% needn't be advertised via service discovery.
+    %% TODO: fix in ejabberd
+    %% true = is_feature_advertised(Config, ?NS_PRIVACY),
+    I1 = send(Config, #iq{type = get, sub_els = [#privacy{}]}),
+    #iq{type = result, id = I1, sub_els = [#privacy{}]} = recv(),
+    JID = <<"tybalt@example.com">>,
+    I2 = send(Config,
+              #iq{type = set,
+                  sub_els = [#privacy{
+                                list = [#privacy_list{
+                                           name = <<"public">>,
+                                           privacy_item =
+                                               [#privacy_item{
+                                                   type = jid,
+                                                   order = 3,
+                                                   action = deny,
+                                                   stanza = 'presence-in',
+                                                   value = JID}]}]}]}),
+    #iq{type = result, id = I2, sub_els = []} = recv(),
+    _Push1 = #iq{type = set, id = PushI1,
+                   sub_els = [#privacy{
+                                 list = [#privacy_list{
+                                            name = <<"public">>}]}]} = recv(),
+    %% BUG: ejabberd replies on this result
+    %% TODO: this should be fixed in ejabberd
+    %% _ = send(Config, Push1#iq{type = result, sub_els = []}),
+    I3 = send(Config, #iq{type = set,
+                          sub_els = [#privacy{active = <<"public">>}]}),
+    #iq{type = result, id = I3, sub_els = []} = recv(),
+    I4 = send(Config, #iq{type = set,
+                          sub_els = [#privacy{default = <<"public">>}]}),
+    #iq{type = result, id = I4, sub_els = []} = recv(),
+    I5 = send(Config, #iq{type = get, sub_els = [#privacy{}]}),
+    #iq{type = result, id = I5,
+        sub_els = [#privacy{default = <<"public">>,
+                            active = <<"public">>,
+                            list = [#privacy_list{name = <<"public">>}]}]} = recv(),
+    I6 = send(Config,
+              #iq{type = set, sub_els = [#privacy{default = none}]}),
+    #iq{type = result, id = I6, sub_els = []} = recv(),
+    I7 = send(Config, #iq{type = set, sub_els = [#privacy{active = none}]}),
+    #iq{type = result, id = I7, sub_els = []} = recv(),
+    I8 = send(Config, #iq{type = set,
+                          sub_els = [#privacy{
+                                        list =
+                                            [#privacy_list{
+                                                name = <<"public">>}]}]}),
+    #iq{type = result, id = I8, sub_els = []} = recv(),
+    %% BUG: We should receive this:
+    %% _Push2 = #iq{type = set, id = PushI2, sub_els = []} = recv(),
+    %% TODO: this should be fixed in ejabberd
+    _Push2 = #iq{type = set, id = PushI2,
+                   sub_els = [#privacy{
+                                 list = [#privacy_list{
+                                            name = <<"public">>}]}]} = recv(),
+    disconnect(Config).
+
+blocking(Config) ->
+    true = is_feature_advertised(Config, ?NS_BLOCKING),
+    JID = jlib:make_jid(<<"romeo">>, <<"montague.net">>, <<>>),
+    I1 = send(Config, #iq{type = get, sub_els = [#block_list{}]}),
+    #iq{type = result, id = I1, sub_els = [#block_list{}]} = recv(),
+    I2 = send(Config, #iq{type = set,
+                          sub_els = [#block{block_item = [JID]}]}),
+    #iq{type = result, id = I2, sub_els = []} = recv(),
+    #iq{type = set, id = _,
+          sub_els = [#privacy{list = [#privacy_list{}]}]} = recv(),
+    #iq{type = set, id = _,
+          sub_els = [#block{block_item = [JID]}]} = recv(),
+    I3 = send(Config, #iq{type = set,
+                          sub_els = [#unblock{block_item = [JID]}]}),
+    #iq{type = result, id = I3, sub_els = []} = recv(),
+    #iq{type = set, id = _,
+        sub_els = [#privacy{list = [#privacy_list{}]}]} = recv(),
+    #iq{type = set, id = _,
+        sub_els = [#unblock{block_item = [JID]}]} = recv(),
+    disconnect(Config).
+
+vcard(Config) ->
+    true = is_feature_advertised(Config, ?NS_VCARD),
+    VCard =
+        #vcard{fn = <<"Peter Saint-Andre">>,
+               n = #vcard_name{family = <<"Saint-Andre">>,
+                               given = <<"Peter">>},
+               nickname = <<"stpeter">>,
+               bday = <<"1966-08-06">>,
+               adr = [#vcard_adr{work = true,
+                                 extadd = <<"Suite 600">>,
+                                 street = <<"1899 Wynkoop Street">>,
+                                 locality = <<"Denver">>,
+                                 region = <<"CO">>,
+                                 pcode = <<"80202">>,
+                                 ctry = <<"USA">>},
+                      #vcard_adr{home = true,
+                                 locality = <<"Denver">>,
+                                 region = <<"CO">>,
+                                 pcode = <<"80209">>,
+                                 ctry = <<"USA">>}],
+               tel = [#vcard_tel{work = true,voice = true,
+                                 number = <<"303-308-3282">>},
+                      #vcard_tel{home = true,voice = true,
+                                 number = <<"303-555-1212">>}],
+               email = [#vcard_email{internet = true,pref = true,
+                                     userid = <<"stpeter@jabber.org">>}],
+               jabberid = <<"stpeter@jabber.org">>,
+               title = <<"Executive Director">>,role = <<"Patron Saint">>,
+               org = #vcard_org{name = <<"XMPP Standards Foundation">>},
+               url = <<"http://www.xmpp.org/xsf/people/stpeter.shtml">>,
+               desc = <<"More information about me is located on my "
+                        "personal website: http://www.saint-andre.com/">>},
+    I1 = send(Config, #iq{type = set, sub_els = [VCard]}),
+    #iq{type = result, id = I1, sub_els = []} = recv(),
+    I2 = send(Config, #iq{type = get, sub_els = [#vcard{}]}),
+    %% TODO: check if VCard == VCard1.
+    #iq{type = result, id = I2, sub_els = [_VCard1]} = recv(),
+    disconnect(Config).
+
+stats(Config) ->
+    ServerJID = server_jid(Config),
+    ID = send(Config, #iq{type = get, sub_els = [#stats{}],
+                          to = server_jid(Config)}),
+    #iq{type = result, id = ID, sub_els = [#stats{stat = Stats}]} = recv(),
+    lists:foreach(
+      fun(#stat{name = Name} = Stat) ->
+              I = send(Config, #iq{type = get,
+                                   sub_els = [#stats{stat = [Stat]}],
+                                   to = server_jid(Config)}),
+              #iq{type = result, id = I, sub_els = [_|_]} = recv()
+      end, Stats),
+    disconnect(Config).
+
+pubsub(Config) ->
+    true = is_feature_advertised(Config, ?NS_PUBSUB),
+    %% Get subscriptions
+    %% true = is_feature_advertised(Config, ?PUBSUB("retrieve-subscriptions")),
+    %% I1 = send(Config, #iq{type = get, to = pubsub_jid(Config),
+    %%                       sub_els = [#pubsub{subscriptions = {none, []}}]}),
+    %% #iq{type = result, id = I1,
+    %%     sub_els = [#pubsub{subscriptions = {none, []}}]} = recv(),
+    %% %% Get affiliations
+    %% true = is_feature_advertised(Config, ?PUBSUB("retrieve-affiliations")),
+    %% I2 = send(Config, #iq{type = get, to = pubsub_jid(Config),
+    %%                       sub_els = [#pubsub{affiliations = []}]}),
+    %% #iq{type = result, id = I2,
+    %%     sub_els = [#pubsub{affiliations = []}]} = recv(),
+
+    true = is_feature_advertised(Config, ?NS_PUBSUB),
+    %% Publish <presence/> element within node "presence"
+    ItemID = randoms:get_string(),
+    Node = <<"presence">>,
+    Item = #pubsub_item{id = ItemID, sub_els = [#presence{}]},
+    I1 = send(Config,
+              #iq{type = set, to = pubsub_jid(Config),
+                  sub_els = [#pubsub{publish = {Node, [Item]}}]}),
+    #iq{type = result, id = I1,
+        sub_els = [#pubsub{publish = {<<"presence">>,
+                                      [#pubsub_item{id = ItemID}]}}]} = recv(),
+    %% Subscribe to node "presence"
+    I2 = send(Config,
+              #iq{type = set, to = pubsub_jid(Config),
+                  sub_els = [#pubsub{subscribe = {Node, my_jid(Config)}}]}),
+    #message{sub_els = [#pubsub_event{}, #delay{}]} = recv(),
+    #iq{type = result, id = I2} = recv(),
+    disconnect(Config).
+
+auth_md5(Config) ->
+    Mechs = ?config(mechs, Config),
+    case lists:member(<<"DIGEST-MD5">>, Mechs) of
+        true ->
+            disconnect(auth_SASL(<<"DIGEST-MD5">>, Config));
+        false ->
+            disconnect(Config),
+            {skipped, 'DIGEST-MD5_not_available'}
+    end.
+
+auth_plain(Config) ->
+    Mechs = ?config(mechs, Config),
+    case lists:member(<<"PLAIN">>, Mechs) of
+        true ->
+            disconnect(auth_SASL(<<"PLAIN">>, Config));
+        false ->
+            disconnect(Config),
+            {skipped, 'PLAIN_not_available'}
+    end.
+
+auth_SASL(Mech, Config) ->
+    {Response, SASL} = sasl_new(Mech,
+                                ?config(user, Config),
+                                ?config(server, Config),
+                                ?config(password, Config)),
+    send(Config, #sasl_auth{mechanism = Mech, cdata = Response}),
+    wait_auth_SASL_result([{sasl, SASL}|Config]).
+
+wait_auth_SASL_result(Config) ->
+    case recv() of
+        #sasl_success{} ->
+            ejabberd_socket:reset_stream(?config(socket, Config)),
+            send_text(Config,
+                      io_lib:format(?STREAM_HEADER,
+                                    [?config(server, Config)])),
+            {xmlstreamstart, <<"stream:stream">>, Attrs} = recv(),
+            <<"jabber:client">> = xml:get_attr_s(<<"xmlns">>, Attrs),
+            <<"1.0">> = xml:get_attr_s(<<"version">>, Attrs),
+            #stream_features{} = recv(),
+            Config;
+        #sasl_challenge{cdata = ClientIn} ->
+            {Response, SASL} = (?config(sasl, Config))(ClientIn),
+            send(Config, #sasl_response{cdata = Response}),
+            Config1 = proplists:delete(sasl, Config),
+            wait_auth_SASL_result([{sasl, SASL}|Config1]);
+        #sasl_failure{} ->
+            ct:fail(sasl_auth_failed)
+    end.
+
+%%%===================================================================
+%%% Aux functions
+%%%===================================================================
+re_register(Config) ->
+    User = ?config(user, Config),
+    Server = ?config(server, Config),
+    Pass = ?config(password, Config),
+    {atomic, ok} = ejabberd_auth:try_register(User, Server, Pass),
+    ok.
+
+recv() ->
+    receive
+        {'$gen_event', {xmlstreamelement, El}} ->
+            ct:log("recv: ~p", [El]),
+            xmpp_codec:decode(El);
+        {'$gen_event', Event} ->
+            Event
+    end.
+
+send_text(Config, Text) ->
+    ejabberd_socket:send(?config(socket, Config), Text).
+
+send(State, Pkt) ->
+    {NewID, NewPkt} = case Pkt of
+                          #message{id = I} ->
+                              ID = id(I),
+                              {ID, Pkt#message{id = ID}};
+                          #presence{id = I} ->
+                              ID = id(I),
+                              {ID, Pkt#presence{id = ID}};
+                          #iq{id = I} ->
+                              ID = id(I),
+                              {ID, Pkt#iq{id = ID}};
+                          _ ->
+                              {undefined, Pkt}
+                      end,
+    El = xmpp_codec:encode(NewPkt),
+    ct:log("sent: ~p", [El]),
+    ok = send_text(State, xml:element_to_binary(El)),
+    NewID.
+
+sasl_new(<<"PLAIN">>, User, Server, Password) ->
+    {<<User/binary, $@, Server/binary, 0, User/binary, 0, Password/binary>>,
+     fun (_) -> {error, <<"Invalid SASL challenge">>} end};
+sasl_new(<<"DIGEST-MD5">>, User, Server, Password) ->
+    {<<"">>,
+     fun (ServerIn) ->
+            case cyrsasl_digest:parse(ServerIn) of
+              bad -> {error, <<"Invalid SASL challenge">>};
+              KeyVals ->
+                  Nonce = xml:get_attr_s(<<"nonce">>, KeyVals),
+                  CNonce = id(),
+                  DigestURI = <<"xmpp/", Server/binary>>,
+                  Realm = Server,
+                  NC = <<"00000001">>,
+                  QOP = <<"auth">>,
+                  AuthzId = <<"">>,
+                  MyResponse = response(User, Password, Nonce, AuthzId,
+                                        Realm, CNonce, DigestURI, NC, QOP,
+                                        <<"AUTHENTICATE">>),
+                  ServerResponse = response(User, Password, Nonce,
+                                            AuthzId, Realm, CNonce, DigestURI,
+                                            NC, QOP, <<"">>),
+                  Resp = <<"username=\"", User/binary, "\",realm=\"",
+                           Realm/binary, "\",nonce=\"", Nonce/binary,
+                           "\",cnonce=\"", CNonce/binary, "\",nc=", NC/binary,
+                           ",qop=", QOP/binary, ",digest-uri=\"",
+                           DigestURI/binary, "\",response=\"",
+                           MyResponse/binary, "\"">>,
+                  {Resp,
+                   fun (ServerIn2) ->
+                           case cyrsasl_digest:parse(ServerIn2) of
+                             bad -> {error, <<"Invalid SASL challenge">>};
+                             KeyVals2 ->
+                                 RspAuth = xml:get_attr_s(<<"rspauth">>,
+                                                          KeyVals2),
+                                 if RspAuth == ServerResponse ->
+                                        {<<"">>,
+                                         fun (_) ->
+                                                 {error,
+                                                  <<"Invalid SASL challenge">>}
+                                         end};
+                                    true ->
+                                        {error, <<"Invalid SASL challenge">>}
+                                 end
+                           end
+                   end}
+            end
+     end}.
+
+hex(S) ->
+    sha:to_hexlist(S).
+
+response(User, Passwd, Nonce, AuthzId, Realm, CNonce,
+        DigestURI, NC, QOP, A2Prefix) ->
+    A1 = case AuthzId of
+          <<"">> ->
+              <<((crypto:md5(<<User/binary, ":", Realm/binary, ":",
+                               Passwd/binary>>)))/binary,
+                ":", Nonce/binary, ":", CNonce/binary>>;
+          _ ->
+              <<((crypto:md5(<<User/binary, ":", Realm/binary, ":",
+                               Passwd/binary>>)))/binary,
+                ":", Nonce/binary, ":", CNonce/binary, ":",
+                AuthzId/binary>>
+        end,
+    A2 = case QOP of
+          <<"auth">> ->
+              <<A2Prefix/binary, ":", DigestURI/binary>>;
+          _ ->
+              <<A2Prefix/binary, ":", DigestURI/binary,
+                ":00000000000000000000000000000000">>
+        end,
+    T = <<(hex((crypto:md5(A1))))/binary, ":", Nonce/binary,
+         ":", NC/binary, ":", CNonce/binary, ":", QOP/binary,
+         ":", (hex((crypto:md5(A2))))/binary>>,
+    hex((crypto:md5(T))).
+
+my_jid(Config) ->
+    jlib:make_jid(?config(user, Config),
+                  ?config(server, Config),
+                  ?config(resource, Config)).
+
+server_jid(Config) ->
+    jlib:make_jid(<<>>, ?config(server, Config), <<>>).
+
+pubsub_jid(Config) ->
+    Server = ?config(server, Config),
+    jlib:make_jid(<<>>, <<"pubsub.", Server/binary>>, <<>>).
+
+id() ->
+    id(undefined).
+
+id(undefined) ->
+    randoms:get_string();
+id(ID) ->
+    ID.
+
+is_feature_advertised(Config, Feature) ->
+    ID = send(Config, #iq{type = get, sub_els = [#disco_info{}],
+                          to = server_jid(Config)}),
+    #iq{type = result, id = ID,
+        sub_els = [#disco_info{feature = Features}]} = recv(),
+    lists:member(Feature, Features).
+
+bookmark_conference() ->
+    #bookmark_conference{name = <<"Some name">>,
+                         autojoin = true,
+                         jid = jlib:make_jid(
+                                 <<"some">>,
+                                 <<"some.conference.org">>,
+                                 <<>>)}.
diff --git a/test/ejabberd_SUITE_data/ejabberd.cfg b/test/ejabberd_SUITE_data/ejabberd.cfg
new file mode 100644 (file)
index 0000000..bcb0a00
--- /dev/null
@@ -0,0 +1,77 @@
+{loglevel, 4}.
+{hosts, ["localhost"]}.
+{listen,
+ [
+  {5222, ejabberd_c2s, [
+                       {access, c2s},
+                       {shaper, c2s_shaper},
+                       {max_stanza_size, 65536}
+                      ]},
+  {5269, ejabberd_s2s_in, [
+                          {shaper, s2s_shaper},
+                          {max_stanza_size, 131072}
+                         ]},
+  {5280, ejabberd_http, [
+                        captcha
+                       ]}
+ ]}.
+{define_macro, 'DB_TYPE', internal}.
+{auth_method, 'DB_TYPE'}.
+{shaper, normal, {maxrate, 1000}}.
+{shaper, fast, {maxrate, 50000}}.
+{max_fsm_queue, 1000}.
+{acl, local, {user_regexp, ""}}.
+{access, max_user_sessions, [{10, all}]}.
+{access, max_user_offline_messages, [{5000, admin}, {100, all}]}.
+{access, local, [{allow, local}]}.
+{access, c2s, [{deny, blocked},
+              {allow, all}]}.
+{access, c2s_shaper, [{none, admin},
+                     {normal, all}]}.
+{access, s2s_shaper, [{fast, all}]}.
+{access, announce, [{allow, admin}]}.
+{access, configure, [{allow, admin}]}.
+{access, muc_admin, [{allow, admin}]}.
+{access, muc_create, [{allow, local}]}.
+{access, muc, [{allow, all}]}.
+{access, pubsub_createnode, [{allow, local}]}.
+{access, register, [{allow, all}]}.
+{language, "en"}.
+{modules,
+ [
+  {mod_adhoc,     []},
+  {mod_announce,  [{db_type, 'DB_TYPE'}]},
+  {mod_blocking,  [{db_type, 'DB_TYPE'}]},
+  {mod_caps,      [{db_type, 'DB_TYPE'}]},
+  {mod_configure, []},
+  {mod_disco,     []},
+  {mod_last,      [{db_type, 'DB_TYPE'}]},
+  {mod_muc,       []},
+  {mod_offline,   [{db_type, 'DB_TYPE'}]},
+  {mod_ping,      []},
+  {mod_privacy,   [{db_type, 'DB_TYPE'}]},
+  {mod_private,   [{db_type, 'DB_TYPE'}]},
+  {mod_proxy65,   []},
+  {mod_pubsub,   [
+                  {access_createnode, pubsub_createnode},
+                  {ignore_pep_from_offline, true},
+                  %%{ignore_pep_from_offline, false},
+                  {last_item_cache, false},
+                  {plugins, ["flat", "hometree", "pep", "public",
+                             "private", "mb"]}
+                 ]},
+  {mod_register,  [
+                  {welcome_message, {"Welcome!",
+                                    "Hi.\nWelcome to this XMPP server."}}
+                 ]},
+  {mod_roster,    [{db_type, 'DB_TYPE'}]},
+  {mod_stats,     []},
+  {mod_time,      []},
+  {mod_vcard,     [{db_type, 'DB_TYPE'}]},
+  {mod_version,   []}
+ ]}.
+
+%%% Local Variables:
+%%% mode: erlang
+%%% End:
+%%% vim: set filetype=erlang tabstop=8 foldmarker=%%%',%%%. foldmethod=marker:
similarity index 83%
rename from src/p1_prof.erl
rename to tools/p1_prof.erl
index d4f4b885671a662742f9567eed8d6fc38b9d4998..cec73d506b2f676ebf9da49bfbd6195b350ae63a 100644 (file)
         reds/0, reds/1, trace/1, help/0,
         q/0, m/0, r/0, q/1, m/1, r/1]).
 
--define(APPS, [ejabberd, mnesia]).
+-define(TRACE_FILE, "/tmp/fprof.trace").
+-define(ANALYSIS_FILE, "/tmp/fprof.analysis").
 
 %%====================================================================
 %% API
 %%====================================================================
 eprof_start() ->
     eprof:start(),
-    case lists:keyfind(running, 1, application:info()) of
-       {_, Apps} ->
-           case get_procs(?APPS, Apps) of
-               [] ->
-                   {error, no_procs_found};
-               Procs ->
-                   eprof:start_profiling(Procs)
-           end;
-       _ ->
-           {error, no_app_info}
+    case get_procs() of
+        [] ->
+            {error, no_procs_found};
+        Procs ->
+            eprof:start_profiling(Procs)
     end.
 
 fprof_start() ->
     fprof_start(0).
 
 fprof_start(Duration) ->
-    case lists:keyfind(running, 1, application:info()) of
-       {_, Apps} ->
-           case get_procs(?APPS, Apps) of
-               [] ->
-                   {error, no_procs_found};
-               Procs ->
-                   fprof:trace([start, {procs, Procs}]),
-                   io:format("Profiling started~n"),
-                   if Duration > 0 ->
-                           timer:sleep(Duration*1000),
-                           fprof:trace([stop]),
-                           fprof:stop();
-                      true->
-                           ok
-                   end
-           end;
-       _ ->
-           {error, no_app_info}
+    case get_procs() of
+        [] ->
+            {error, no_procs_found};
+        Procs ->
+            case fprof:trace([start, {procs, Procs}, {file, ?TRACE_FILE}]) of
+                ok ->
+                    io:format("Profiling started, writing trace data to ~s~n",
+                              [?TRACE_FILE]),
+                    if Duration > 0 ->
+                            timer:sleep(Duration*1000),
+                            fprof:trace([stop]),
+                            fprof:stop();
+                       true->
+                            ok
+                    end;
+                Err ->
+                    io:format("Couldn't start profiling: ~p~n", [Err]),
+                    Err
+            end
     end.
 
 fprof_stop() ->
     fprof:trace([stop]),
-    fprof:profile(),
-    fprof:analyse([totals, no_details, {sort, own},
-                  no_callers, {dest, "fprof.analysis"}]),
-    fprof:stop(),
-    format_fprof_analyze().
+    case fprof:profile([{file, ?TRACE_FILE}]) of
+        ok ->
+            case fprof:analyse([totals, no_details, {sort, own},
+                                no_callers, {dest, ?ANALYSIS_FILE}]) of
+                ok ->
+                    fprof:stop(),
+                    format_fprof_analyze();
+                Err ->
+                    io:format("Couldn't analyze: ~p~n", [Err]),
+                    Err
+            end;
+        Err ->
+            io:format("Couldn't compile a trace into profile data: ~p~n",
+                      [Err]),
+            Err
+    end.
 
 fprof_analyze() ->
     fprof_stop().
@@ -175,35 +183,11 @@ trace_loop() ->
 %%====================================================================
 %% Internal functions
 %%====================================================================
-get_procs(Apps, AppList) ->
-    io:format("Searching for processes to profile...~n", []),
-    Procs = lists:flatmap(
-             fun({App, Leader}) when is_pid(Leader) ->
-                     case lists:member(App, Apps) of
-                         true ->
-                             get_procs(Leader);
-                         false ->
-                             []
-                     end;
-                (_) ->
-                     []
-             end, AppList),
-    io:format("Found ~p processes~n", [length(Procs)]),
-    Procs.
-
-get_procs(Leader) ->
-    lists:filter(
-      fun(Pid) ->
-             case process_info(Pid, group_leader) of
-                 {_, Leader} ->
-                     true;
-                 _ ->
-                     false
-             end
-      end, processes()).
+get_procs() ->
+    processes().
 
 format_fprof_analyze() ->
-    case file:consult("fprof.analysis") of
+    case file:consult(?ANALYSIS_FILE) of
        {ok, [_, [{totals, _, _, TotalOWN}] | Rest]} ->
            OWNs = lists:flatmap(
                     fun({MFA, _, _, OWN}) ->
diff --git a/tools/xmpp_codec.erl b/tools/xmpp_codec.erl
new file mode 100644 (file)
index 0000000..37ea49d
--- /dev/null
@@ -0,0 +1,10301 @@
+-module(xmpp_codec).
+
+-export([decode/1, encode/1]).
+
+decode({xmlel, _name, _attrs, _} = _el) ->
+    case {_name, xml:get_attr_s(<<"xmlns">>, _attrs)} of
+      {<<"delay">>, <<"urn:xmpp:delay">>} ->
+         decode_delay_delay(_el);
+      {<<"pubsub">>,
+       <<"http://jabber.org/protocol/pubsub">>} ->
+         decode_pubsub_pubsub(_el);
+      {<<"event">>,
+       <<"http://jabber.org/protocol/pubsub#event">>} ->
+         decode_pubsub_event_event(_el);
+      {<<"items">>, <<>>} -> decode_pubsub_items_items(_el);
+      {<<"item">>, <<>>} -> decode_pubsub_item_item(_el);
+      {<<"affiliation">>, <<>>} ->
+         decode_pubsub_affiliation_affiliation(_el);
+      {<<"subscription">>, <<>>} ->
+         decode_pubsub_subscription_subscription(_el);
+      {<<"x">>, <<"jabber:x:data">>} -> decode_xdata_x(_el);
+      {<<"field">>, <<>>} -> decode_xfield_field(_el);
+      {<<"vCard">>, <<"vcard-temp">>} ->
+         decode_vcard_vCard(_el);
+      {<<"KEY">>, <<>>} -> decode_vcard_key_KEY(_el);
+      {<<"SOUND">>, <<>>} -> decode_vcard_sound_SOUND(_el);
+      {<<"ORG">>, <<>>} -> decode_vcard_org_ORG(_el);
+      {<<"PHOTO">>, <<>>} -> decode_vcard_photo_PHOTO(_el);
+      {<<"LOGO">>, <<>>} -> decode_vcard_logo_LOGO(_el);
+      {<<"EXTVAL">>, <<>>} -> decode_vcard_extval_EXTVAL(_el);
+      {<<"BINVAL">>, <<>>} -> decode_vcard_binval_BINVAL(_el);
+      {<<"TYPE">>, <<>>} -> decode_vcard_type_TYPE(_el);
+      {<<"GEO">>, <<>>} -> decode_vcard_geo_GEO(_el);
+      {<<"EMAIL">>, <<>>} -> decode_vcard_email_EMAIL(_el);
+      {<<"TEL">>, <<>>} -> decode_vcard_tel_TEL(_el);
+      {<<"LABEL">>, <<>>} -> decode_vcard_label_LABEL(_el);
+      {<<"ADR">>, <<>>} -> decode_vcard_adr_ADR(_el);
+      {<<"N">>, <<>>} -> decode_vcard_name_N(_el);
+      {<<"stream:error">>, <<>>} ->
+         'decode_stream_error_stream:error'(_el);
+      {<<"time">>, <<"urn:xmpp:time">>} ->
+         decode_time_time(_el);
+      {<<"ping">>, <<"urn:xmpp:ping">>} ->
+         decode_ping_ping(_el);
+      {<<"session">>,
+       <<"urn:ietf:params:xml:ns:xmpp-session">>} ->
+         decode_session_session(_el);
+      {<<"register">>,
+       <<"http://jabber.org/features/iq-register">>} ->
+         decode_register_register(_el);
+      {<<"c">>, <<"http://jabber.org/protocol/caps">>} ->
+         decode_caps_c(_el);
+      {<<"ack">>, <<"p1:ack">>} -> decode_p1_ack_ack(_el);
+      {<<"rebind">>, <<"p1:rebind">>} ->
+         decode_p1_rebind_rebind(_el);
+      {<<"push">>, <<"p1:push">>} -> decode_p1_push_push(_el);
+      {<<"stream:features">>, <<>>} ->
+         'decode_stream_features_stream:features'(_el);
+      {<<"failure">>,
+       <<"urn:ietf:params:xml:ns:xmpp-tls">>} ->
+         decode_starttls_failure_failure(_el);
+      {<<"proceed">>,
+       <<"urn:ietf:params:xml:ns:xmpp-tls">>} ->
+         decode_starttls_proceed_proceed(_el);
+      {<<"starttls">>,
+       <<"urn:ietf:params:xml:ns:xmpp-tls">>} ->
+         decode_starttls_starttls(_el);
+      {<<"mechanisms">>,
+       <<"urn:ietf:params:xml:ns:xmpp-sasl">>} ->
+         decode_sasl_mechanisms_mechanisms(_el);
+      {<<"mechanism">>, <<>>} ->
+         decode_sasl_mechanism_mechanism(_el);
+      {<<"failure">>,
+       <<"urn:ietf:params:xml:ns:xmpp-sasl">>} ->
+         decode_sasl_failure_failure(_el);
+      {<<"success">>,
+       <<"urn:ietf:params:xml:ns:xmpp-sasl">>} ->
+         decode_sasl_success_success(_el);
+      {<<"response">>,
+       <<"urn:ietf:params:xml:ns:xmpp-sasl">>} ->
+         decode_sasl_response_response(_el);
+      {<<"challenge">>,
+       <<"urn:ietf:params:xml:ns:xmpp-sasl">>} ->
+         decode_sasl_challenge_challenge(_el);
+      {<<"abort">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} ->
+         decode_sasl_abort_abort(_el);
+      {<<"auth">>, <<"urn:ietf:params:xml:ns:xmpp-sasl">>} ->
+         decode_sasl_auth_auth(_el);
+      {<<"bind">>, <<"urn:ietf:params:xml:ns:xmpp-bind">>} ->
+         decode_bind_bind(_el);
+      {<<"error">>, <<>>} -> decode_error_error(_el);
+      {<<"presence">>, <<>>} -> decode_presence_presence(_el);
+      {<<"message">>, <<>>} -> decode_message_message(_el);
+      {<<"iq">>, <<>>} -> decode_iq_iq(_el);
+      {<<"query">>, <<"http://jabber.org/protocol/stats">>} ->
+         decode_stats_query(_el);
+      {<<"storage">>, <<"storage:bookmarks">>} ->
+         decode_storage_bookmarks_storage(_el);
+      {<<"conference">>, <<>>} ->
+         decode_bookmark_conference_conference(_el);
+      {<<"query">>, <<"jabber:iq:private">>} ->
+         decode_private_query(_el);
+      {<<"query">>,
+       <<"http://jabber.org/protocol/disco#items">>} ->
+         decode_disco_items_query(_el);
+      {<<"query">>,
+       <<"http://jabber.org/protocol/disco#info">>} ->
+         decode_disco_info_query(_el);
+      {<<"blocklist">>, <<"urn:xmpp:blocking">>} ->
+         decode_block_list_blocklist(_el);
+      {<<"unblock">>, <<"urn:xmpp:blocking">>} ->
+         decode_unblock_unblock(_el);
+      {<<"block">>, <<"urn:xmpp:blocking">>} ->
+         decode_block_block(_el);
+      {<<"item">>, <<>>} -> decode_block_item_item(_el);
+      {<<"query">>, <<"jabber:iq:privacy">>} ->
+         decode_privacy_query(_el);
+      {<<"item">>, <<>>} -> decode_privacy_item_item(_el);
+      {<<"query">>, <<"jabber:iq:roster">>} ->
+         decode_roster_query(_el);
+      {<<"query">>, <<"jabber:iq:version">>} ->
+         decode_version_query(_el);
+      {<<"query">>, <<"jabber:iq:last">>} ->
+         decode_last_query(_el);
+      {_name, _xmlns} ->
+         erlang:error({unknown_tag, _name, _xmlns})
+    end.
+
+encode({delay, _, _} = _r) ->
+    hd(encode_delay_delay(_r, []));
+encode({pubsub, _, _, _, _} = _r) ->
+    hd(encode_pubsub_pubsub(_r, []));
+encode({pubsub_event, _} = _r) ->
+    hd(encode_pubsub_event_event(_r, []));
+encode({pubsub_items, _, _, _, _} = _r) ->
+    hd(encode_pubsub_items_items(_r, []));
+encode({pubsub_item, _, _} = _r) ->
+    hd(encode_pubsub_item_item(_r, []));
+encode({pubsub_affiliation, _, _} = _r) ->
+    hd(encode_pubsub_affiliation_affiliation(_r, []));
+encode({pubsub_subscription, _, _, _, _} = _r) ->
+    hd(encode_pubsub_subscription_subscription(_r, []));
+encode({xdata, _, _, _, _, _, _} = _r) ->
+    hd(encode_xdata_x(_r, []));
+encode({xfield, _, _, _, _, _, _, _} = _r) ->
+    hd(encode_xfield_field(_r, []));
+encode({vcard, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+       _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} =
+          _r) ->
+    hd(encode_vcard_vCard(_r, []));
+encode({vcard_key, _, _} = _r) ->
+    hd(encode_vcard_key_KEY(_r, []));
+encode({vcard_sound, _, _, _} = _r) ->
+    hd(encode_vcard_sound_SOUND(_r, []));
+encode({vcard_org, _, _} = _r) ->
+    hd(encode_vcard_org_ORG(_r, []));
+encode({vcard_photo, _, _, _} = _r) ->
+    hd(encode_vcard_photo_PHOTO(_r, []));
+encode({vcard_logo, _, _, _} = _r) ->
+    hd(encode_vcard_logo_LOGO(_r, []));
+encode({vcard_geo, _, _} = _r) ->
+    hd(encode_vcard_geo_GEO(_r, []));
+encode({vcard_email, _, _, _, _, _, _} = _r) ->
+    hd(encode_vcard_email_EMAIL(_r, []));
+encode({vcard_tel, _, _, _, _, _, _, _, _, _, _, _, _,
+       _, _} =
+          _r) ->
+    hd(encode_vcard_tel_TEL(_r, []));
+encode({vcard_label, _, _, _, _, _, _, _, _} = _r) ->
+    hd(encode_vcard_label_LABEL(_r, []));
+encode({vcard_adr, _, _, _, _, _, _, _, _, _, _, _, _,
+       _, _} =
+          _r) ->
+    hd(encode_vcard_adr_ADR(_r, []));
+encode({vcard_name, _, _, _, _, _} = _r) ->
+    hd(encode_vcard_name_N(_r, []));
+encode({stream_error, _, _} = _r) ->
+    hd('encode_stream_error_stream:error'(_r, []));
+encode({time, _, _} = _r) ->
+    hd(encode_time_time(_r, []));
+encode({ping} = _r) -> hd(encode_ping_ping(_r, []));
+encode({session} = _r) ->
+    hd(encode_session_session(_r, []));
+encode({register} = _r) ->
+    hd(encode_register_register(_r, []));
+encode({caps, _, _, _} = _r) ->
+    hd(encode_caps_c(_r, []));
+encode({p1_ack} = _r) -> hd(encode_p1_ack_ack(_r, []));
+encode({p1_rebind} = _r) ->
+    hd(encode_p1_rebind_rebind(_r, []));
+encode({p1_push} = _r) ->
+    hd(encode_p1_push_push(_r, []));
+encode({stream_features, _} = _r) ->
+    hd('encode_stream_features_stream:features'(_r, []));
+encode({starttls_failure} = _r) ->
+    hd(encode_starttls_failure_failure(_r, []));
+encode({starttls_proceed} = _r) ->
+    hd(encode_starttls_proceed_proceed(_r, []));
+encode({starttls, _} = _r) ->
+    hd(encode_starttls_starttls(_r, []));
+encode({sasl_mechanisms, _} = _r) ->
+    hd(encode_sasl_mechanisms_mechanisms(_r, []));
+encode({sasl_failure, _, _} = _r) ->
+    hd(encode_sasl_failure_failure(_r, []));
+encode({sasl_success, _} = _r) ->
+    hd(encode_sasl_success_success(_r, []));
+encode({sasl_response, _} = _r) ->
+    hd(encode_sasl_response_response(_r, []));
+encode({sasl_challenge, _} = _r) ->
+    hd(encode_sasl_challenge_challenge(_r, []));
+encode({sasl_abort} = _r) ->
+    hd(encode_sasl_abort_abort(_r, []));
+encode({sasl_auth, _, _} = _r) ->
+    hd(encode_sasl_auth_auth(_r, []));
+encode({bind, _, _} = _r) ->
+    hd(encode_bind_bind(_r, []));
+encode({error, _, _, _, _} = _r) ->
+    hd(encode_error_error(_r, []));
+encode({presence, _, _, _, _, _, _, _, _, _, _} = _r) ->
+    hd(encode_presence_presence(_r, []));
+encode({message, _, _, _, _, _, _, _, _, _, _} = _r) ->
+    hd(encode_message_message(_r, []));
+encode({iq, _, _, _, _, _, _, _} = _r) ->
+    hd(encode_iq_iq(_r, []));
+encode({stats, _} = _r) ->
+    hd(encode_stats_query(_r, []));
+encode({bookmark_storage, _, _} = _r) ->
+    hd(encode_storage_bookmarks_storage(_r, []));
+encode({bookmark_conference, _, _, _, _, _} = _r) ->
+    hd(encode_bookmark_conference_conference(_r, []));
+encode({private, _} = _r) ->
+    hd(encode_private_query(_r, []));
+encode({disco_items, _, _} = _r) ->
+    hd(encode_disco_items_query(_r, []));
+encode({disco_info, _, _, _, _} = _r) ->
+    hd(encode_disco_info_query(_r, []));
+encode({block_list} = _r) ->
+    hd(encode_block_list_blocklist(_r, []));
+encode({unblock, _} = _r) ->
+    hd(encode_unblock_unblock(_r, []));
+encode({block, _} = _r) ->
+    hd(encode_block_block(_r, []));
+encode({privacy, _, _, _} = _r) ->
+    hd(encode_privacy_query(_r, []));
+encode({privacy_item, _, _, _, _, _} = _r) ->
+    hd(encode_privacy_item_item(_r, []));
+encode({roster, _, _} = _r) ->
+    hd(encode_roster_query(_r, []));
+encode({version, _, _, _} = _r) ->
+    hd(encode_version_query(_r, []));
+encode({last, _, _} = _r) ->
+    hd(encode_last_query(_r, [])).
+
+enc_bool(false) -> <<"false">>;
+enc_bool(true) -> <<"true">>.
+
+dec_bool(<<"false">>) -> false;
+dec_bool(<<"true">>) -> true.
+
+resourceprep(R) ->
+    case jlib:resourceprep(R) of
+      error -> erlang:error(badarg);
+      R1 -> R1
+    end.
+
+enc_jid(J) -> jlib:jid_to_string(J).
+
+dec_jid(Val) ->
+    case jlib:string_to_jid(Val) of
+      error -> erlang:error(badarg);
+      J -> J
+    end.
+
+enc_utc(Val) -> jlib:now_to_utc_string(Val).
+
+dec_utc(Val) ->
+    {_, _, _} = jlib:datetime_string_to_timestamp(Val).
+
+enc_tzo({H, M}) ->
+    Sign = if H >= 0 -> <<>>;
+             true -> <<"-">>
+          end,
+    list_to_binary([Sign,
+                   io_lib:format("~2..0w:~2..0w", [H, M])]).
+
+dec_tzo(Val) ->
+    [H1, M1] = str:tokens(Val, <<":">>),
+    H = erlang:binary_to_integer(H1),
+    M = erlang:binary_to_integer(M1),
+    if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end.
+
+decode_last_query({xmlel, _, _attrs, _els}) ->
+    Seconds = decode_last_query_attrs(_attrs, undefined),
+    Text = decode_last_query_els(_els, <<>>),
+    {last, Seconds, Text}.
+
+decode_last_query_els([{xmlcdata, _data} | _els],
+                     Text) ->
+    decode_last_query_els(_els,
+                         <<Text/binary, _data/binary>>);
+decode_last_query_els([_ | _els], Text) ->
+    decode_last_query_els(_els, Text);
+decode_last_query_els([], Text) ->
+    decode_last_query_cdata(Text).
+
+decode_last_query_attrs([{<<"seconds">>, _val}
+                        | _attrs],
+                       _Seconds) ->
+    decode_last_query_attrs(_attrs, _val);
+decode_last_query_attrs([_ | _attrs], Seconds) ->
+    decode_last_query_attrs(_attrs, Seconds);
+decode_last_query_attrs([], Seconds) ->
+    decode_last_query_seconds(Seconds).
+
+encode_last_query(undefined, _acc) -> _acc;
+encode_last_query({last, Seconds, Text}, _acc) ->
+    _els = encode_last_query_cdata(Text, []),
+    _attrs = encode_last_query_seconds(Seconds,
+                                      [{<<"xmlns">>, <<"jabber:iq:last">>}]),
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_last_query_seconds(undefined) -> undefined;
+decode_last_query_seconds(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"seconds">>,
+                       <<"query">>, <<"jabber:iq:last">>});
+      _res -> _res
+    end.
+
+encode_last_query_seconds(undefined, _acc) -> _acc;
+encode_last_query_seconds(_val, _acc) ->
+    [{<<"seconds">>, xml_gen:enc_int(_val)} | _acc].
+
+decode_last_query_cdata(<<>>) -> undefined;
+decode_last_query_cdata(_val) -> _val.
+
+encode_last_query_cdata(undefined, _acc) -> _acc;
+encode_last_query_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_version_query({xmlel, _, _attrs, _els}) ->
+    {Os, Version, Name} = decode_version_query_els(_els,
+                                                  undefined, undefined,
+                                                  undefined),
+    {version, Name, Version, Os}.
+
+decode_version_query_els([{xmlel, <<"os">>, _attrs, _} =
+                             _el
+                         | _els],
+                        Os, Version, Name) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_version_query_els(_els,
+                                  decode_version_query_os(_el), Version, Name);
+      _ -> decode_version_query_els(_els, Os, Version, Name)
+    end;
+decode_version_query_els([{xmlel, <<"version">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Os, Version, Name) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_version_query_els(_els, Os,
+                                  decode_version_query_version(_el), Name);
+      _ -> decode_version_query_els(_els, Os, Version, Name)
+    end;
+decode_version_query_els([{xmlel, <<"name">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Os, Version, Name) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_version_query_els(_els, Os, Version,
+                                  decode_version_query_name(_el));
+      _ -> decode_version_query_els(_els, Os, Version, Name)
+    end;
+decode_version_query_els([_ | _els], Os, Version,
+                        Name) ->
+    decode_version_query_els(_els, Os, Version, Name);
+decode_version_query_els([], Os, Version, Name) ->
+    {Os, Version, Name}.
+
+encode_version_query(undefined, _acc) -> _acc;
+encode_version_query({version, Name, Version, Os},
+                    _acc) ->
+    _els = encode_version_query_name(Name,
+                                    encode_version_query_version(Version,
+                                                                 encode_version_query_os(Os,
+                                                                                         []))),
+    _attrs = [{<<"xmlns">>, <<"jabber:iq:version">>}],
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_version_query_os({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_version_query_os_els(_els, <<>>), Cdata.
+
+decode_version_query_os_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_version_query_os_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_version_query_os_els([_ | _els], Cdata) ->
+    decode_version_query_os_els(_els, Cdata);
+decode_version_query_os_els([], Cdata) ->
+    decode_version_query_os_cdata(Cdata).
+
+encode_version_query_os(undefined, _acc) -> _acc;
+encode_version_query_os(Cdata, _acc) ->
+    _els = encode_version_query_os_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"os">>, _attrs, _els} | _acc].
+
+decode_version_query_os_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"os">>, <<>>});
+decode_version_query_os_cdata(_val) -> _val.
+
+encode_version_query_os_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_version_query_version({xmlel, _, _attrs,
+                             _els}) ->
+    Cdata = decode_version_query_version_els(_els, <<>>),
+    Cdata.
+
+decode_version_query_version_els([{xmlcdata, _data}
+                                 | _els],
+                                Cdata) ->
+    decode_version_query_version_els(_els,
+                                    <<Cdata/binary, _data/binary>>);
+decode_version_query_version_els([_ | _els], Cdata) ->
+    decode_version_query_version_els(_els, Cdata);
+decode_version_query_version_els([], Cdata) ->
+    decode_version_query_version_cdata(Cdata).
+
+encode_version_query_version(undefined, _acc) -> _acc;
+encode_version_query_version(Cdata, _acc) ->
+    _els = encode_version_query_version_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"version">>, _attrs, _els} | _acc].
+
+decode_version_query_version_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"version">>,
+                 <<>>});
+decode_version_query_version_cdata(_val) -> _val.
+
+encode_version_query_version_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_version_query_name({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_version_query_name_els(_els, <<>>),
+    Cdata.
+
+decode_version_query_name_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_version_query_name_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_version_query_name_els([_ | _els], Cdata) ->
+    decode_version_query_name_els(_els, Cdata);
+decode_version_query_name_els([], Cdata) ->
+    decode_version_query_name_cdata(Cdata).
+
+encode_version_query_name(undefined, _acc) -> _acc;
+encode_version_query_name(Cdata, _acc) ->
+    _els = encode_version_query_name_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"name">>, _attrs, _els} | _acc].
+
+decode_version_query_name_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"name">>, <<>>});
+decode_version_query_name_cdata(_val) -> _val.
+
+encode_version_query_name_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_roster_query({xmlel, _, _attrs, _els}) ->
+    Ver = decode_roster_query_attrs(_attrs, undefined),
+    Item = decode_roster_query_els(_els, []),
+    {roster, Item, Ver}.
+
+decode_roster_query_els([{xmlel, <<"item">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Item) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_roster_query_els(_els,
+                                 [decode_roster_query_item(_el) | Item]);
+      _ -> decode_roster_query_els(_els, Item)
+    end;
+decode_roster_query_els([_ | _els], Item) ->
+    decode_roster_query_els(_els, Item);
+decode_roster_query_els([], Item) ->
+    lists:reverse(Item).
+
+decode_roster_query_attrs([{<<"ver">>, _val} | _attrs],
+                         _Ver) ->
+    decode_roster_query_attrs(_attrs, _val);
+decode_roster_query_attrs([_ | _attrs], Ver) ->
+    decode_roster_query_attrs(_attrs, Ver);
+decode_roster_query_attrs([], Ver) ->
+    decode_roster_query_ver(Ver).
+
+encode_roster_query(undefined, _acc) -> _acc;
+encode_roster_query({roster, Item, Ver}, _acc) ->
+    _els = encode_roster_query_item(Item, []),
+    _attrs = encode_roster_query_ver(Ver,
+                                    [{<<"xmlns">>, <<"jabber:iq:roster">>}]),
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_roster_query_ver(undefined) -> undefined;
+decode_roster_query_ver(_val) -> _val.
+
+encode_roster_query_ver(undefined, _acc) -> _acc;
+encode_roster_query_ver(_val, _acc) ->
+    [{<<"ver">>, _val} | _acc].
+
+decode_roster_query_item({xmlel, _, _attrs, _els}) ->
+    {Ask, Subscription, Name, Jid} =
+       decode_roster_query_item_attrs(_attrs, undefined,
+                                      undefined, undefined, undefined),
+    Groups = decode_roster_query_item_els(_els, []),
+    {roster_item, Jid, Name, Groups, Subscription, Ask}.
+
+decode_roster_query_item_els([{xmlel, <<"group">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Groups) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_roster_query_item_els(_els,
+                                      [decode_roster_query_item_group(_el)
+                                       | Groups]);
+      _ -> decode_roster_query_item_els(_els, Groups)
+    end;
+decode_roster_query_item_els([_ | _els], Groups) ->
+    decode_roster_query_item_els(_els, Groups);
+decode_roster_query_item_els([], Groups) ->
+    lists:reverse(Groups).
+
+decode_roster_query_item_attrs([{<<"ask">>, _val}
+                               | _attrs],
+                              _Ask, Subscription, Name, Jid) ->
+    decode_roster_query_item_attrs(_attrs, _val,
+                                  Subscription, Name, Jid);
+decode_roster_query_item_attrs([{<<"subscription">>,
+                                _val}
+                               | _attrs],
+                              Ask, _Subscription, Name, Jid) ->
+    decode_roster_query_item_attrs(_attrs, Ask, _val, Name,
+                                  Jid);
+decode_roster_query_item_attrs([{<<"name">>, _val}
+                               | _attrs],
+                              Ask, Subscription, _Name, Jid) ->
+    decode_roster_query_item_attrs(_attrs, Ask,
+                                  Subscription, _val, Jid);
+decode_roster_query_item_attrs([{<<"jid">>, _val}
+                               | _attrs],
+                              Ask, Subscription, Name, _Jid) ->
+    decode_roster_query_item_attrs(_attrs, Ask,
+                                  Subscription, Name, _val);
+decode_roster_query_item_attrs([_ | _attrs], Ask,
+                              Subscription, Name, Jid) ->
+    decode_roster_query_item_attrs(_attrs, Ask,
+                                  Subscription, Name, Jid);
+decode_roster_query_item_attrs([], Ask, Subscription,
+                              Name, Jid) ->
+    {decode_roster_query_item_ask(Ask),
+     decode_roster_query_item_subscription(Subscription),
+     decode_roster_query_item_name(Name),
+     decode_roster_query_item_jid(Jid)}.
+
+encode_roster_query_item([], _acc) -> _acc;
+encode_roster_query_item([{roster_item, Jid, Name,
+                          Groups, Subscription, Ask}
+                         | _tail],
+                        _acc) ->
+    _els = encode_roster_query_item_group(Groups, []),
+    _attrs = encode_roster_query_item_jid(Jid,
+                                         encode_roster_query_item_name(Name,
+                                                                       encode_roster_query_item_subscription(Subscription,
+                                                                                                             encode_roster_query_item_ask(Ask,
+                                                                                                                                          [])))),
+    encode_roster_query_item(_tail,
+                            [{xmlel, <<"item">>, _attrs, _els} | _acc]).
+
+decode_roster_query_item_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"item">>,
+                 <<>>});
+decode_roster_query_item_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_roster_query_item_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
+
+decode_roster_query_item_name(undefined) -> undefined;
+decode_roster_query_item_name(_val) -> _val.
+
+encode_roster_query_item_name(undefined, _acc) -> _acc;
+encode_roster_query_item_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_roster_query_item_subscription(undefined) ->
+    none;
+decode_roster_query_item_subscription(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [none, to, from, both, remove])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"subscription">>,
+                       <<"item">>, <<>>});
+      _res -> _res
+    end.
+
+encode_roster_query_item_subscription(none, _acc) ->
+    _acc;
+encode_roster_query_item_subscription(_val, _acc) ->
+    [{<<"subscription">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_roster_query_item_ask(undefined) -> undefined;
+decode_roster_query_item_ask(_val) ->
+    case catch xml_gen:dec_enum(_val, [subscribe]) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"ask">>, <<"item">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_roster_query_item_ask(undefined, _acc) -> _acc;
+encode_roster_query_item_ask(_val, _acc) ->
+    [{<<"ask">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_roster_query_item_group({xmlel, _, _attrs,
+                               _els}) ->
+    Cdata = decode_roster_query_item_group_els(_els, <<>>),
+    Cdata.
+
+decode_roster_query_item_group_els([{xmlcdata, _data}
+                                   | _els],
+                                  Cdata) ->
+    decode_roster_query_item_group_els(_els,
+                                      <<Cdata/binary, _data/binary>>);
+decode_roster_query_item_group_els([_ | _els], Cdata) ->
+    decode_roster_query_item_group_els(_els, Cdata);
+decode_roster_query_item_group_els([], Cdata) ->
+    decode_roster_query_item_group_cdata(Cdata).
+
+encode_roster_query_item_group([], _acc) -> _acc;
+encode_roster_query_item_group([Cdata | _tail], _acc) ->
+    _els = encode_roster_query_item_group_cdata(Cdata, []),
+    _attrs = [],
+    encode_roster_query_item_group(_tail,
+                                  [{xmlel, <<"group">>, _attrs, _els} | _acc]).
+
+decode_roster_query_item_group_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"group">>, <<>>});
+decode_roster_query_item_group_cdata(_val) -> _val.
+
+encode_roster_query_item_group_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_privacy_item_item({xmlel, _, _attrs, _els}) ->
+    {Value, Type, Action, Order} =
+       decode_privacy_item_item_attrs(_attrs, undefined,
+                                      undefined, undefined, undefined),
+    Stanza = decode_privacy_item_item_els(_els, undefined),
+    {privacy_item, Order, Action, Type, Value, Stanza}.
+
+decode_privacy_item_item_els([{xmlel,
+                              <<"presence-out">>, _attrs, _} =
+                                 _el
+                             | _els],
+                            Stanza) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_item_item_els(_els,
+                                      'decode_privacy_item_item_presence-out'(_el));
+      _ -> decode_privacy_item_item_els(_els, Stanza)
+    end;
+decode_privacy_item_item_els([{xmlel, <<"presence-in">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Stanza) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_item_item_els(_els,
+                                      'decode_privacy_item_item_presence-in'(_el));
+      _ -> decode_privacy_item_item_els(_els, Stanza)
+    end;
+decode_privacy_item_item_els([{xmlel, <<"iq">>, _attrs,
+                              _} =
+                                 _el
+                             | _els],
+                            Stanza) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_item_item_els(_els,
+                                      decode_privacy_item_item_iq(_el));
+      _ -> decode_privacy_item_item_els(_els, Stanza)
+    end;
+decode_privacy_item_item_els([{xmlel, <<"message">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Stanza) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_item_item_els(_els,
+                                      decode_privacy_item_item_message(_el));
+      _ -> decode_privacy_item_item_els(_els, Stanza)
+    end;
+decode_privacy_item_item_els([_ | _els], Stanza) ->
+    decode_privacy_item_item_els(_els, Stanza);
+decode_privacy_item_item_els([], Stanza) -> Stanza.
+
+decode_privacy_item_item_attrs([{<<"value">>, _val}
+                               | _attrs],
+                              _Value, Type, Action, Order) ->
+    decode_privacy_item_item_attrs(_attrs, _val, Type,
+                                  Action, Order);
+decode_privacy_item_item_attrs([{<<"type">>, _val}
+                               | _attrs],
+                              Value, _Type, Action, Order) ->
+    decode_privacy_item_item_attrs(_attrs, Value, _val,
+                                  Action, Order);
+decode_privacy_item_item_attrs([{<<"action">>, _val}
+                               | _attrs],
+                              Value, Type, _Action, Order) ->
+    decode_privacy_item_item_attrs(_attrs, Value, Type,
+                                  _val, Order);
+decode_privacy_item_item_attrs([{<<"order">>, _val}
+                               | _attrs],
+                              Value, Type, Action, _Order) ->
+    decode_privacy_item_item_attrs(_attrs, Value, Type,
+                                  Action, _val);
+decode_privacy_item_item_attrs([_ | _attrs], Value,
+                              Type, Action, Order) ->
+    decode_privacy_item_item_attrs(_attrs, Value, Type,
+                                  Action, Order);
+decode_privacy_item_item_attrs([], Value, Type, Action,
+                              Order) ->
+    {decode_privacy_item_item_value(Value),
+     decode_privacy_item_item_type(Type),
+     decode_privacy_item_item_action(Action),
+     decode_privacy_item_item_order(Order)}.
+
+'encode_privacy_item_item_$stanza'(undefined, _acc) ->
+    _acc;
+'encode_privacy_item_item_$stanza'('presence-out' = _r,
+                                  _acc) ->
+    'encode_privacy_item_item_presence-out'(_r, _acc);
+'encode_privacy_item_item_$stanza'('presence-in' = _r,
+                                  _acc) ->
+    'encode_privacy_item_item_presence-in'(_r, _acc);
+'encode_privacy_item_item_$stanza'(iq = _r, _acc) ->
+    encode_privacy_item_item_iq(_r, _acc);
+'encode_privacy_item_item_$stanza'(message = _r,
+                                  _acc) ->
+    encode_privacy_item_item_message(_r, _acc).
+
+encode_privacy_item_item([], _acc) -> _acc;
+encode_privacy_item_item([{privacy_item, Order, Action,
+                          Type, Value, Stanza}
+                         | _tail],
+                        _acc) ->
+    _els = 'encode_privacy_item_item_$stanza'(Stanza, []),
+    _attrs = encode_privacy_item_item_order(Order,
+                                           encode_privacy_item_item_action(Action,
+                                                                           encode_privacy_item_item_type(Type,
+                                                                                                         encode_privacy_item_item_value(Value,
+                                                                                                                                        [])))),
+    encode_privacy_item_item(_tail,
+                            [{xmlel, <<"item">>, _attrs, _els} | _acc]).
+
+decode_privacy_item_item_action(undefined) ->
+    erlang:error({missing_attr, <<"action">>, <<"item">>,
+                 <<>>});
+decode_privacy_item_item_action(_val) ->
+    case catch xml_gen:dec_enum(_val, [allow, deny]) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"action">>, <<"item">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_privacy_item_item_action(_val, _acc) ->
+    [{<<"action">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_privacy_item_item_order(undefined) ->
+    erlang:error({missing_attr, <<"order">>, <<"item">>,
+                 <<>>});
+decode_privacy_item_item_order(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"order">>, <<"item">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_privacy_item_item_order(_val, _acc) ->
+    [{<<"order">>, xml_gen:enc_int(_val)} | _acc].
+
+decode_privacy_item_item_type(undefined) -> undefined;
+decode_privacy_item_item_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [group, jid, subscription])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"item">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_privacy_item_item_type(undefined, _acc) -> _acc;
+encode_privacy_item_item_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_privacy_item_item_value(undefined) -> undefined;
+decode_privacy_item_item_value(_val) -> _val.
+
+encode_privacy_item_item_value(undefined, _acc) -> _acc;
+encode_privacy_item_item_value(_val, _acc) ->
+    [{<<"value">>, _val} | _acc].
+
+'decode_privacy_item_item_presence-out'({xmlel, _,
+                                        _attrs, _els}) ->
+    'presence-out'.
+
+'encode_privacy_item_item_presence-out'(undefined,
+                                       _acc) ->
+    _acc;
+'encode_privacy_item_item_presence-out'('presence-out',
+                                       _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"presence-out">>, _attrs, _els} | _acc].
+
+'decode_privacy_item_item_presence-in'({xmlel, _,
+                                       _attrs, _els}) ->
+    'presence-in'.
+
+'encode_privacy_item_item_presence-in'(undefined,
+                                      _acc) ->
+    _acc;
+'encode_privacy_item_item_presence-in'('presence-in',
+                                      _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"presence-in">>, _attrs, _els} | _acc].
+
+decode_privacy_item_item_iq({xmlel, _, _attrs, _els}) ->
+    iq.
+
+encode_privacy_item_item_iq(undefined, _acc) -> _acc;
+encode_privacy_item_item_iq(iq, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"iq">>, _attrs, _els} | _acc].
+
+decode_privacy_item_item_message({xmlel, _, _attrs,
+                                 _els}) ->
+    message.
+
+encode_privacy_item_item_message(undefined, _acc) ->
+    _acc;
+encode_privacy_item_item_message(message, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"message">>, _attrs, _els} | _acc].
+
+decode_privacy_query({xmlel, _, _attrs, _els}) ->
+    {Active, Default, List} = decode_privacy_query_els(_els,
+                                                      undefined, undefined,
+                                                      []),
+    {privacy, List, Default, Active}.
+
+decode_privacy_query_els([{xmlel, <<"active">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Active, Default, List) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_query_els(_els,
+                                  decode_privacy_query_active(_el), Default,
+                                  List);
+      _ ->
+         decode_privacy_query_els(_els, Active, Default, List)
+    end;
+decode_privacy_query_els([{xmlel, <<"default">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Active, Default, List) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_query_els(_els, Active,
+                                  decode_privacy_query_default(_el), List);
+      _ ->
+         decode_privacy_query_els(_els, Active, Default, List)
+    end;
+decode_privacy_query_els([{xmlel, <<"list">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Active, Default, List) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_query_els(_els, Active, Default,
+                                  [decode_privacy_query_list(_el) | List]);
+      _ ->
+         decode_privacy_query_els(_els, Active, Default, List)
+    end;
+decode_privacy_query_els([_ | _els], Active, Default,
+                        List) ->
+    decode_privacy_query_els(_els, Active, Default, List);
+decode_privacy_query_els([], Active, Default, List) ->
+    {Active, Default, lists:reverse(List)}.
+
+encode_privacy_query(undefined, _acc) -> _acc;
+encode_privacy_query({privacy, List, Default, Active},
+                    _acc) ->
+    _els = encode_privacy_query_list(List,
+                                    encode_privacy_query_default(Default,
+                                                                 encode_privacy_query_active(Active,
+                                                                                             []))),
+    _attrs = [{<<"xmlns">>, <<"jabber:iq:privacy">>}],
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_privacy_query_active({xmlel, _, _attrs, _els}) ->
+    Name = decode_privacy_query_active_attrs(_attrs,
+                                            undefined),
+    Name.
+
+decode_privacy_query_active_attrs([{<<"name">>, _val}
+                                  | _attrs],
+                                 _Name) ->
+    decode_privacy_query_active_attrs(_attrs, _val);
+decode_privacy_query_active_attrs([_ | _attrs], Name) ->
+    decode_privacy_query_active_attrs(_attrs, Name);
+decode_privacy_query_active_attrs([], Name) ->
+    decode_privacy_query_active_name(Name).
+
+encode_privacy_query_active(undefined, _acc) -> _acc;
+encode_privacy_query_active(Name, _acc) ->
+    _els = [],
+    _attrs = encode_privacy_query_active_name(Name, []),
+    [{xmlel, <<"active">>, _attrs, _els} | _acc].
+
+decode_privacy_query_active_name(undefined) -> none;
+decode_privacy_query_active_name(_val) -> _val.
+
+encode_privacy_query_active_name(none, _acc) -> _acc;
+encode_privacy_query_active_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_privacy_query_default({xmlel, _, _attrs,
+                             _els}) ->
+    Name = decode_privacy_query_default_attrs(_attrs,
+                                             undefined),
+    Name.
+
+decode_privacy_query_default_attrs([{<<"name">>, _val}
+                                   | _attrs],
+                                  _Name) ->
+    decode_privacy_query_default_attrs(_attrs, _val);
+decode_privacy_query_default_attrs([_ | _attrs],
+                                  Name) ->
+    decode_privacy_query_default_attrs(_attrs, Name);
+decode_privacy_query_default_attrs([], Name) ->
+    decode_privacy_query_default_name(Name).
+
+encode_privacy_query_default(undefined, _acc) -> _acc;
+encode_privacy_query_default(Name, _acc) ->
+    _els = [],
+    _attrs = encode_privacy_query_default_name(Name, []),
+    [{xmlel, <<"default">>, _attrs, _els} | _acc].
+
+decode_privacy_query_default_name(undefined) -> none;
+decode_privacy_query_default_name(_val) -> _val.
+
+encode_privacy_query_default_name(none, _acc) -> _acc;
+encode_privacy_query_default_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_privacy_query_list({xmlel, _, _attrs, _els}) ->
+    Name = decode_privacy_query_list_attrs(_attrs,
+                                          undefined),
+    Privacy_item = decode_privacy_query_list_els(_els, []),
+    {privacy_list, Name, Privacy_item}.
+
+decode_privacy_query_list_els([{xmlel, <<"item">>,
+                               _attrs, _} =
+                                  _el
+                              | _els],
+                             Privacy_item) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_privacy_query_list_els(_els,
+                                       [decode_privacy_item_item(_el)
+                                        | Privacy_item]);
+      _ -> decode_privacy_query_list_els(_els, Privacy_item)
+    end;
+decode_privacy_query_list_els([_ | _els],
+                             Privacy_item) ->
+    decode_privacy_query_list_els(_els, Privacy_item);
+decode_privacy_query_list_els([], Privacy_item) ->
+    lists:reverse(Privacy_item).
+
+decode_privacy_query_list_attrs([{<<"name">>, _val}
+                                | _attrs],
+                               _Name) ->
+    decode_privacy_query_list_attrs(_attrs, _val);
+decode_privacy_query_list_attrs([_ | _attrs], Name) ->
+    decode_privacy_query_list_attrs(_attrs, Name);
+decode_privacy_query_list_attrs([], Name) ->
+    decode_privacy_query_list_name(Name).
+
+encode_privacy_query_list([], _acc) -> _acc;
+encode_privacy_query_list([{privacy_list, Name,
+                           Privacy_item}
+                          | _tail],
+                         _acc) ->
+    _els = encode_privacy_item_item(Privacy_item, []),
+    _attrs = encode_privacy_query_list_name(Name, []),
+    encode_privacy_query_list(_tail,
+                             [{xmlel, <<"list">>, _attrs, _els} | _acc]).
+
+decode_privacy_query_list_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>, <<"list">>,
+                 <<>>});
+decode_privacy_query_list_name(_val) -> _val.
+
+encode_privacy_query_list_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_block_item_item({xmlel, _, _attrs, _els}) ->
+    Jid = decode_block_item_item_attrs(_attrs, undefined),
+    Jid.
+
+decode_block_item_item_attrs([{<<"jid">>, _val}
+                             | _attrs],
+                            _Jid) ->
+    decode_block_item_item_attrs(_attrs, _val);
+decode_block_item_item_attrs([_ | _attrs], Jid) ->
+    decode_block_item_item_attrs(_attrs, Jid);
+decode_block_item_item_attrs([], Jid) ->
+    decode_block_item_item_jid(Jid).
+
+encode_block_item_item([], _acc) -> _acc;
+encode_block_item_item([Jid | _tail], _acc) ->
+    _els = [],
+    _attrs = encode_block_item_item_jid(Jid, []),
+    encode_block_item_item(_tail,
+                          [{xmlel, <<"item">>, _attrs, _els} | _acc]).
+
+decode_block_item_item_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"item">>,
+                 <<>>});
+decode_block_item_item_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_block_item_item_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
+
+decode_block_block({xmlel, _, _attrs, _els}) ->
+    Block_item = decode_block_block_els(_els, []),
+    {block, Block_item}.
+
+decode_block_block_els([{xmlel, <<"item">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Block_item) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_block_block_els(_els,
+                                [decode_block_item_item(_el) | Block_item]);
+      _ -> decode_block_block_els(_els, Block_item)
+    end;
+decode_block_block_els([_ | _els], Block_item) ->
+    decode_block_block_els(_els, Block_item);
+decode_block_block_els([], Block_item) ->
+    lists:reverse(Block_item).
+
+encode_block_block(undefined, _acc) -> _acc;
+encode_block_block({block, Block_item}, _acc) ->
+    _els = encode_block_item_item(Block_item, []),
+    _attrs = [{<<"xmlns">>, <<"urn:xmpp:blocking">>}],
+    [{xmlel, <<"block">>, _attrs, _els} | _acc].
+
+decode_unblock_unblock({xmlel, _, _attrs, _els}) ->
+    Block_item = decode_unblock_unblock_els(_els, []),
+    {unblock, Block_item}.
+
+decode_unblock_unblock_els([{xmlel, <<"item">>, _attrs,
+                            _} =
+                               _el
+                           | _els],
+                          Block_item) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_unblock_unblock_els(_els,
+                                    [decode_block_item_item(_el)
+                                     | Block_item]);
+      _ -> decode_unblock_unblock_els(_els, Block_item)
+    end;
+decode_unblock_unblock_els([_ | _els], Block_item) ->
+    decode_unblock_unblock_els(_els, Block_item);
+decode_unblock_unblock_els([], Block_item) ->
+    lists:reverse(Block_item).
+
+encode_unblock_unblock(undefined, _acc) -> _acc;
+encode_unblock_unblock({unblock, Block_item}, _acc) ->
+    _els = encode_block_item_item(Block_item, []),
+    _attrs = [{<<"xmlns">>, <<"urn:xmpp:blocking">>}],
+    [{xmlel, <<"unblock">>, _attrs, _els} | _acc].
+
+decode_block_list_blocklist({xmlel, _, _attrs, _els}) ->
+    {block_list}.
+
+encode_block_list_blocklist(undefined, _acc) -> _acc;
+encode_block_list_blocklist({block_list}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>, <<"urn:xmpp:blocking">>}],
+    [{xmlel, <<"blocklist">>, _attrs, _els} | _acc].
+
+decode_disco_info_query({xmlel, _, _attrs, _els}) ->
+    Node = decode_disco_info_query_attrs(_attrs, undefined),
+    {Xdata, Feature, Identity} =
+       decode_disco_info_query_els(_els, [], [], []),
+    {disco_info, Node, Identity, Feature, Xdata}.
+
+decode_disco_info_query_els([{xmlel, <<"x">>, _attrs,
+                             _} =
+                                _el
+                            | _els],
+                           Xdata, Feature, Identity) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"jabber:x:data">> ->
+         decode_disco_info_query_els(_els,
+                                     [decode_xdata_x(_el) | Xdata], Feature,
+                                     Identity);
+      _ ->
+         decode_disco_info_query_els(_els, Xdata, Feature,
+                                     Identity)
+    end;
+decode_disco_info_query_els([{xmlel, <<"feature">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Xdata, Feature, Identity) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_disco_info_query_els(_els, Xdata,
+                                     [decode_disco_info_query_feature(_el)
+                                      | Feature],
+                                     Identity);
+      _ ->
+         decode_disco_info_query_els(_els, Xdata, Feature,
+                                     Identity)
+    end;
+decode_disco_info_query_els([{xmlel, <<"identity">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Xdata, Feature, Identity) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_disco_info_query_els(_els, Xdata, Feature,
+                                     [decode_disco_info_query_identity(_el)
+                                      | Identity]);
+      _ ->
+         decode_disco_info_query_els(_els, Xdata, Feature,
+                                     Identity)
+    end;
+decode_disco_info_query_els([_ | _els], Xdata, Feature,
+                           Identity) ->
+    decode_disco_info_query_els(_els, Xdata, Feature,
+                               Identity);
+decode_disco_info_query_els([], Xdata, Feature,
+                           Identity) ->
+    {lists:reverse(Xdata), lists:reverse(Feature),
+     lists:reverse(Identity)}.
+
+decode_disco_info_query_attrs([{<<"node">>, _val}
+                              | _attrs],
+                             _Node) ->
+    decode_disco_info_query_attrs(_attrs, _val);
+decode_disco_info_query_attrs([_ | _attrs], Node) ->
+    decode_disco_info_query_attrs(_attrs, Node);
+decode_disco_info_query_attrs([], Node) ->
+    decode_disco_info_query_node(Node).
+
+encode_disco_info_query(undefined, _acc) -> _acc;
+encode_disco_info_query({disco_info, Node, Identity,
+                        Feature, Xdata},
+                       _acc) ->
+    _els = encode_disco_info_query_identity(Identity,
+                                           encode_disco_info_query_feature(Feature,
+                                                                           encode_xdata_x(Xdata,
+                                                                                          []))),
+    _attrs = encode_disco_info_query_node(Node,
+                                         [{<<"xmlns">>,
+                                           <<"http://jabber.org/protocol/disco#info">>}]),
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_disco_info_query_node(undefined) -> undefined;
+decode_disco_info_query_node(_val) -> _val.
+
+encode_disco_info_query_node(undefined, _acc) -> _acc;
+encode_disco_info_query_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_disco_info_query_feature({xmlel, _, _attrs,
+                                _els}) ->
+    Var = decode_disco_info_query_feature_attrs(_attrs,
+                                               undefined),
+    Var.
+
+decode_disco_info_query_feature_attrs([{<<"var">>, _val}
+                                      | _attrs],
+                                     _Var) ->
+    decode_disco_info_query_feature_attrs(_attrs, _val);
+decode_disco_info_query_feature_attrs([_ | _attrs],
+                                     Var) ->
+    decode_disco_info_query_feature_attrs(_attrs, Var);
+decode_disco_info_query_feature_attrs([], Var) ->
+    decode_disco_info_query_feature_var(Var).
+
+encode_disco_info_query_feature([], _acc) -> _acc;
+encode_disco_info_query_feature([Var | _tail], _acc) ->
+    _els = [],
+    _attrs = encode_disco_info_query_feature_var(Var, []),
+    encode_disco_info_query_feature(_tail,
+                                   [{xmlel, <<"feature">>, _attrs, _els}
+                                    | _acc]).
+
+decode_disco_info_query_feature_var(undefined) ->
+    erlang:error({missing_attr, <<"var">>, <<"feature">>,
+                 <<>>});
+decode_disco_info_query_feature_var(_val) -> _val.
+
+encode_disco_info_query_feature_var(_val, _acc) ->
+    [{<<"var">>, _val} | _acc].
+
+decode_disco_info_query_identity({xmlel, _, _attrs,
+                                 _els}) ->
+    {Name, Type, Category} =
+       decode_disco_info_query_identity_attrs(_attrs,
+                                              undefined, undefined, undefined),
+    {Category, Type, Name}.
+
+decode_disco_info_query_identity_attrs([{<<"name">>,
+                                        _val}
+                                       | _attrs],
+                                      _Name, Type, Category) ->
+    decode_disco_info_query_identity_attrs(_attrs, _val,
+                                          Type, Category);
+decode_disco_info_query_identity_attrs([{<<"type">>,
+                                        _val}
+                                       | _attrs],
+                                      Name, _Type, Category) ->
+    decode_disco_info_query_identity_attrs(_attrs, Name,
+                                          _val, Category);
+decode_disco_info_query_identity_attrs([{<<"category">>,
+                                        _val}
+                                       | _attrs],
+                                      Name, Type, _Category) ->
+    decode_disco_info_query_identity_attrs(_attrs, Name,
+                                          Type, _val);
+decode_disco_info_query_identity_attrs([_ | _attrs],
+                                      Name, Type, Category) ->
+    decode_disco_info_query_identity_attrs(_attrs, Name,
+                                          Type, Category);
+decode_disco_info_query_identity_attrs([], Name, Type,
+                                      Category) ->
+    {decode_disco_info_query_identity_name(Name),
+     decode_disco_info_query_identity_type(Type),
+     decode_disco_info_query_identity_category(Category)}.
+
+encode_disco_info_query_identity([], _acc) -> _acc;
+encode_disco_info_query_identity([{Category, Type, Name}
+                                 | _tail],
+                                _acc) ->
+    _els = [],
+    _attrs =
+       encode_disco_info_query_identity_category(Category,
+                                                 encode_disco_info_query_identity_type(Type,
+                                                                                       encode_disco_info_query_identity_name(Name,
+                                                                                                                             []))),
+    encode_disco_info_query_identity(_tail,
+                                    [{xmlel, <<"identity">>, _attrs, _els}
+                                     | _acc]).
+
+decode_disco_info_query_identity_category(undefined) ->
+    erlang:error({missing_attr, <<"category">>,
+                 <<"identity">>, <<>>});
+decode_disco_info_query_identity_category(_val) -> _val.
+
+encode_disco_info_query_identity_category(_val, _acc) ->
+    [{<<"category">>, _val} | _acc].
+
+decode_disco_info_query_identity_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"identity">>,
+                 <<>>});
+decode_disco_info_query_identity_type(_val) -> _val.
+
+encode_disco_info_query_identity_type(_val, _acc) ->
+    [{<<"type">>, _val} | _acc].
+
+decode_disco_info_query_identity_name(undefined) ->
+    undefined;
+decode_disco_info_query_identity_name(_val) -> _val.
+
+encode_disco_info_query_identity_name(undefined,
+                                     _acc) ->
+    _acc;
+encode_disco_info_query_identity_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_disco_items_query({xmlel, _, _attrs, _els}) ->
+    Node = decode_disco_items_query_attrs(_attrs,
+                                         undefined),
+    Items = decode_disco_items_query_els(_els, []),
+    {disco_items, Node, Items}.
+
+decode_disco_items_query_els([{xmlel, <<"item">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Items) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_disco_items_query_els(_els,
+                                      [decode_disco_items_query_item(_el)
+                                       | Items]);
+      _ -> decode_disco_items_query_els(_els, Items)
+    end;
+decode_disco_items_query_els([_ | _els], Items) ->
+    decode_disco_items_query_els(_els, Items);
+decode_disco_items_query_els([], Items) ->
+    lists:reverse(Items).
+
+decode_disco_items_query_attrs([{<<"node">>, _val}
+                               | _attrs],
+                              _Node) ->
+    decode_disco_items_query_attrs(_attrs, _val);
+decode_disco_items_query_attrs([_ | _attrs], Node) ->
+    decode_disco_items_query_attrs(_attrs, Node);
+decode_disco_items_query_attrs([], Node) ->
+    decode_disco_items_query_node(Node).
+
+encode_disco_items_query(undefined, _acc) -> _acc;
+encode_disco_items_query({disco_items, Node, Items},
+                        _acc) ->
+    _els = encode_disco_items_query_item(Items, []),
+    _attrs = encode_disco_items_query_node(Node,
+                                          [{<<"xmlns">>,
+                                            <<"http://jabber.org/protocol/disco#items">>}]),
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_disco_items_query_node(undefined) -> undefined;
+decode_disco_items_query_node(_val) -> _val.
+
+encode_disco_items_query_node(undefined, _acc) -> _acc;
+encode_disco_items_query_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_disco_items_query_item({xmlel, _, _attrs,
+                              _els}) ->
+    {Node, Name, Jid} =
+       decode_disco_items_query_item_attrs(_attrs, undefined,
+                                           undefined, undefined),
+    {disco_item, Jid, Name, Node}.
+
+decode_disco_items_query_item_attrs([{<<"node">>, _val}
+                                    | _attrs],
+                                   _Node, Name, Jid) ->
+    decode_disco_items_query_item_attrs(_attrs, _val, Name,
+                                       Jid);
+decode_disco_items_query_item_attrs([{<<"name">>, _val}
+                                    | _attrs],
+                                   Node, _Name, Jid) ->
+    decode_disco_items_query_item_attrs(_attrs, Node, _val,
+                                       Jid);
+decode_disco_items_query_item_attrs([{<<"jid">>, _val}
+                                    | _attrs],
+                                   Node, Name, _Jid) ->
+    decode_disco_items_query_item_attrs(_attrs, Node, Name,
+                                       _val);
+decode_disco_items_query_item_attrs([_ | _attrs], Node,
+                                   Name, Jid) ->
+    decode_disco_items_query_item_attrs(_attrs, Node, Name,
+                                       Jid);
+decode_disco_items_query_item_attrs([], Node, Name,
+                                   Jid) ->
+    {decode_disco_items_query_item_node(Node),
+     decode_disco_items_query_item_name(Name),
+     decode_disco_items_query_item_jid(Jid)}.
+
+encode_disco_items_query_item([], _acc) -> _acc;
+encode_disco_items_query_item([{disco_item, Jid, Name,
+                               Node}
+                              | _tail],
+                             _acc) ->
+    _els = [],
+    _attrs = encode_disco_items_query_item_jid(Jid,
+                                              encode_disco_items_query_item_name(Name,
+                                                                                 encode_disco_items_query_item_node(Node,
+                                                                                                                    []))),
+    encode_disco_items_query_item(_tail,
+                                 [{xmlel, <<"item">>, _attrs, _els} | _acc]).
+
+decode_disco_items_query_item_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"item">>,
+                 <<>>});
+decode_disco_items_query_item_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_disco_items_query_item_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
+
+decode_disco_items_query_item_name(undefined) ->
+    undefined;
+decode_disco_items_query_item_name(_val) -> _val.
+
+encode_disco_items_query_item_name(undefined, _acc) ->
+    _acc;
+encode_disco_items_query_item_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_disco_items_query_item_node(undefined) ->
+    undefined;
+decode_disco_items_query_item_node(_val) -> _val.
+
+encode_disco_items_query_item_node(undefined, _acc) ->
+    _acc;
+encode_disco_items_query_item_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_private_query({xmlel, _, _attrs, _els}) ->
+    __Els = decode_private_query_els(_els, []),
+    {private, __Els}.
+
+decode_private_query_els([{xmlel, _, _, _} = _el
+                         | _els],
+                        __Els) ->
+    decode_private_query_els(_els, [decode(_el) | __Els]);
+decode_private_query_els([_ | _els], __Els) ->
+    decode_private_query_els(_els, __Els);
+decode_private_query_els([], __Els) ->
+    lists:reverse(__Els).
+
+encode_private_query(undefined, _acc) -> _acc;
+encode_private_query({private, __Els}, _acc) ->
+    _els = [encode(_subel) || _subel <- __Els] ++ [],
+    _attrs = [{<<"xmlns">>, <<"jabber:iq:private">>}],
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_bookmark_conference_conference({xmlel, _, _attrs,
+                                      _els}) ->
+    {Autojoin, Jid, Name} =
+       decode_bookmark_conference_conference_attrs(_attrs,
+                                                   undefined, undefined,
+                                                   undefined),
+    {Password, Nick} =
+       decode_bookmark_conference_conference_els(_els,
+                                                 undefined, undefined),
+    {bookmark_conference, Name, Jid, Autojoin, Nick,
+     Password}.
+
+decode_bookmark_conference_conference_els([{xmlel,
+                                           <<"password">>, _attrs, _} =
+                                              _el
+                                          | _els],
+                                         Password, Nick) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_bookmark_conference_conference_els(_els,
+                                                   decode_bookmark_conference_conference_password(_el),
+                                                   Nick);
+      _ ->
+         decode_bookmark_conference_conference_els(_els,
+                                                   Password, Nick)
+    end;
+decode_bookmark_conference_conference_els([{xmlel,
+                                           <<"nick">>, _attrs, _} =
+                                              _el
+                                          | _els],
+                                         Password, Nick) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_bookmark_conference_conference_els(_els,
+                                                   Password,
+                                                   decode_bookmark_conference_conference_nick(_el));
+      _ ->
+         decode_bookmark_conference_conference_els(_els,
+                                                   Password, Nick)
+    end;
+decode_bookmark_conference_conference_els([_ | _els],
+                                         Password, Nick) ->
+    decode_bookmark_conference_conference_els(_els,
+                                             Password, Nick);
+decode_bookmark_conference_conference_els([], Password,
+                                         Nick) ->
+    {Password, Nick}.
+
+decode_bookmark_conference_conference_attrs([{<<"autojoin">>,
+                                             _val}
+                                            | _attrs],
+                                           _Autojoin, Jid, Name) ->
+    decode_bookmark_conference_conference_attrs(_attrs,
+                                               _val, Jid, Name);
+decode_bookmark_conference_conference_attrs([{<<"jid">>,
+                                             _val}
+                                            | _attrs],
+                                           Autojoin, _Jid, Name) ->
+    decode_bookmark_conference_conference_attrs(_attrs,
+                                               Autojoin, _val, Name);
+decode_bookmark_conference_conference_attrs([{<<"name">>,
+                                             _val}
+                                            | _attrs],
+                                           Autojoin, Jid, _Name) ->
+    decode_bookmark_conference_conference_attrs(_attrs,
+                                               Autojoin, Jid, _val);
+decode_bookmark_conference_conference_attrs([_
+                                            | _attrs],
+                                           Autojoin, Jid, Name) ->
+    decode_bookmark_conference_conference_attrs(_attrs,
+                                               Autojoin, Jid, Name);
+decode_bookmark_conference_conference_attrs([],
+                                           Autojoin, Jid, Name) ->
+    {decode_bookmark_conference_conference_autojoin(Autojoin),
+     decode_bookmark_conference_conference_jid(Jid),
+     decode_bookmark_conference_conference_name(Name)}.
+
+encode_bookmark_conference_conference([], _acc) -> _acc;
+encode_bookmark_conference_conference([{bookmark_conference,
+                                       Name, Jid, Autojoin, Nick, Password}
+                                      | _tail],
+                                     _acc) ->
+    _els = encode_bookmark_conference_conference_nick(Nick,
+                                                     encode_bookmark_conference_conference_password(Password,
+                                                                                                    [])),
+    _attrs =
+       encode_bookmark_conference_conference_name(Name,
+                                                  encode_bookmark_conference_conference_jid(Jid,
+                                                                                            encode_bookmark_conference_conference_autojoin(Autojoin,
+                                                                                                                                           []))),
+    encode_bookmark_conference_conference(_tail,
+                                         [{xmlel, <<"conference">>, _attrs,
+                                           _els}
+                                          | _acc]).
+
+decode_bookmark_conference_conference_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>,
+                 <<"conference">>, <<>>});
+decode_bookmark_conference_conference_name(_val) ->
+    _val.
+
+encode_bookmark_conference_conference_name(_val,
+                                          _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_bookmark_conference_conference_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"conference">>,
+                 <<>>});
+decode_bookmark_conference_conference_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>,
+                       <<"conference">>, <<>>});
+      _res -> _res
+    end.
+
+encode_bookmark_conference_conference_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
+
+decode_bookmark_conference_conference_autojoin(undefined) ->
+    false;
+decode_bookmark_conference_conference_autojoin(_val) ->
+    case catch dec_bool(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"autojoin">>,
+                       <<"conference">>, <<>>});
+      _res -> _res
+    end.
+
+encode_bookmark_conference_conference_autojoin(false,
+                                              _acc) ->
+    _acc;
+encode_bookmark_conference_conference_autojoin(_val,
+                                              _acc) ->
+    [{<<"autojoin">>, enc_bool(_val)} | _acc].
+
+decode_bookmark_conference_conference_password({xmlel,
+                                               _, _attrs, _els}) ->
+    Cdata =
+       decode_bookmark_conference_conference_password_els(_els,
+                                                          <<>>),
+    Cdata.
+
+decode_bookmark_conference_conference_password_els([{xmlcdata,
+                                                    _data}
+                                                   | _els],
+                                                  Cdata) ->
+    decode_bookmark_conference_conference_password_els(_els,
+                                                      <<Cdata/binary,
+                                                        _data/binary>>);
+decode_bookmark_conference_conference_password_els([_
+                                                   | _els],
+                                                  Cdata) ->
+    decode_bookmark_conference_conference_password_els(_els,
+                                                      Cdata);
+decode_bookmark_conference_conference_password_els([],
+                                                  Cdata) ->
+    decode_bookmark_conference_conference_password_cdata(Cdata).
+
+encode_bookmark_conference_conference_password(undefined,
+                                              _acc) ->
+    _acc;
+encode_bookmark_conference_conference_password(Cdata,
+                                              _acc) ->
+    _els =
+       encode_bookmark_conference_conference_password_cdata(Cdata,
+                                                            []),
+    _attrs = [],
+    [{xmlel, <<"password">>, _attrs, _els} | _acc].
+
+decode_bookmark_conference_conference_password_cdata(<<>>) ->
+    undefined;
+decode_bookmark_conference_conference_password_cdata(_val) ->
+    _val.
+
+encode_bookmark_conference_conference_password_cdata(undefined,
+                                                    _acc) ->
+    _acc;
+encode_bookmark_conference_conference_password_cdata(_val,
+                                                    _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_bookmark_conference_conference_nick({xmlel, _,
+                                           _attrs, _els}) ->
+    Cdata =
+       decode_bookmark_conference_conference_nick_els(_els,
+                                                      <<>>),
+    Cdata.
+
+decode_bookmark_conference_conference_nick_els([{xmlcdata,
+                                                _data}
+                                               | _els],
+                                              Cdata) ->
+    decode_bookmark_conference_conference_nick_els(_els,
+                                                  <<Cdata/binary,
+                                                    _data/binary>>);
+decode_bookmark_conference_conference_nick_els([_
+                                               | _els],
+                                              Cdata) ->
+    decode_bookmark_conference_conference_nick_els(_els,
+                                                  Cdata);
+decode_bookmark_conference_conference_nick_els([],
+                                              Cdata) ->
+    decode_bookmark_conference_conference_nick_cdata(Cdata).
+
+encode_bookmark_conference_conference_nick(undefined,
+                                          _acc) ->
+    _acc;
+encode_bookmark_conference_conference_nick(Cdata,
+                                          _acc) ->
+    _els =
+       encode_bookmark_conference_conference_nick_cdata(Cdata,
+                                                        []),
+    _attrs = [],
+    [{xmlel, <<"nick">>, _attrs, _els} | _acc].
+
+decode_bookmark_conference_conference_nick_cdata(<<>>) ->
+    undefined;
+decode_bookmark_conference_conference_nick_cdata(_val) ->
+    _val.
+
+encode_bookmark_conference_conference_nick_cdata(undefined,
+                                                _acc) ->
+    _acc;
+encode_bookmark_conference_conference_nick_cdata(_val,
+                                                _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_storage_bookmarks_storage({xmlel, _, _attrs,
+                                 _els}) ->
+    {Url, Conference} =
+       decode_storage_bookmarks_storage_els(_els, [], []),
+    {bookmark_storage, Conference, Url}.
+
+decode_storage_bookmarks_storage_els([{xmlel, <<"url">>,
+                                      _attrs, _} =
+                                         _el
+                                     | _els],
+                                    Url, Conference) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_storage_bookmarks_storage_els(_els,
+                                              [decode_storage_bookmarks_storage_url(_el)
+                                               | Url],
+                                              Conference);
+      _ ->
+         decode_storage_bookmarks_storage_els(_els, Url,
+                                              Conference)
+    end;
+decode_storage_bookmarks_storage_els([{xmlel,
+                                      <<"conference">>, _attrs, _} =
+                                         _el
+                                     | _els],
+                                    Url, Conference) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_storage_bookmarks_storage_els(_els, Url,
+                                              [decode_bookmark_conference_conference(_el)
+                                               | Conference]);
+      _ ->
+         decode_storage_bookmarks_storage_els(_els, Url,
+                                              Conference)
+    end;
+decode_storage_bookmarks_storage_els([_ | _els], Url,
+                                    Conference) ->
+    decode_storage_bookmarks_storage_els(_els, Url,
+                                        Conference);
+decode_storage_bookmarks_storage_els([], Url,
+                                    Conference) ->
+    {lists:reverse(Url), lists:reverse(Conference)}.
+
+encode_storage_bookmarks_storage(undefined, _acc) ->
+    _acc;
+encode_storage_bookmarks_storage({bookmark_storage,
+                                 Conference, Url},
+                                _acc) ->
+    _els = encode_bookmark_conference_conference(Conference,
+                                                encode_storage_bookmarks_storage_url(Url,
+                                                                                     [])),
+    _attrs = [{<<"xmlns">>, <<"storage:bookmarks">>}],
+    [{xmlel, <<"storage">>, _attrs, _els} | _acc].
+
+decode_storage_bookmarks_storage_url({xmlel, _, _attrs,
+                                     _els}) ->
+    {Url, Name} =
+       decode_storage_bookmarks_storage_url_attrs(_attrs,
+                                                  undefined, undefined),
+    {bookmark_url, Name, Url}.
+
+decode_storage_bookmarks_storage_url_attrs([{<<"url">>,
+                                            _val}
+                                           | _attrs],
+                                          _Url, Name) ->
+    decode_storage_bookmarks_storage_url_attrs(_attrs, _val,
+                                              Name);
+decode_storage_bookmarks_storage_url_attrs([{<<"name">>,
+                                            _val}
+                                           | _attrs],
+                                          Url, _Name) ->
+    decode_storage_bookmarks_storage_url_attrs(_attrs, Url,
+                                              _val);
+decode_storage_bookmarks_storage_url_attrs([_ | _attrs],
+                                          Url, Name) ->
+    decode_storage_bookmarks_storage_url_attrs(_attrs, Url,
+                                              Name);
+decode_storage_bookmarks_storage_url_attrs([], Url,
+                                          Name) ->
+    {decode_storage_bookmarks_storage_url_url(Url),
+     decode_storage_bookmarks_storage_url_name(Name)}.
+
+encode_storage_bookmarks_storage_url([], _acc) -> _acc;
+encode_storage_bookmarks_storage_url([{bookmark_url,
+                                      Name, Url}
+                                     | _tail],
+                                    _acc) ->
+    _els = [],
+    _attrs = encode_storage_bookmarks_storage_url_name(Name,
+                                                      encode_storage_bookmarks_storage_url_url(Url,
+                                                                                               [])),
+    encode_storage_bookmarks_storage_url(_tail,
+                                        [{xmlel, <<"url">>, _attrs, _els}
+                                         | _acc]).
+
+decode_storage_bookmarks_storage_url_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>, <<"url">>,
+                 <<>>});
+decode_storage_bookmarks_storage_url_name(_val) -> _val.
+
+encode_storage_bookmarks_storage_url_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_storage_bookmarks_storage_url_url(undefined) ->
+    erlang:error({missing_attr, <<"url">>, <<"url">>,
+                 <<>>});
+decode_storage_bookmarks_storage_url_url(_val) -> _val.
+
+encode_storage_bookmarks_storage_url_url(_val, _acc) ->
+    [{<<"url">>, _val} | _acc].
+
+decode_stats_query({xmlel, _, _attrs, _els}) ->
+    Stat = decode_stats_query_els(_els, []), {stats, Stat}.
+
+decode_stats_query_els([{xmlel, <<"stat">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Stat) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_stats_query_els(_els,
+                                [decode_stats_query_stat(_el) | Stat]);
+      _ -> decode_stats_query_els(_els, Stat)
+    end;
+decode_stats_query_els([_ | _els], Stat) ->
+    decode_stats_query_els(_els, Stat);
+decode_stats_query_els([], Stat) -> lists:reverse(Stat).
+
+encode_stats_query(undefined, _acc) -> _acc;
+encode_stats_query({stats, Stat}, _acc) ->
+    _els = encode_stats_query_stat(Stat, []),
+    _attrs = [{<<"xmlns">>,
+              <<"http://jabber.org/protocol/stats">>}],
+    [{xmlel, <<"query">>, _attrs, _els} | _acc].
+
+decode_stats_query_stat({xmlel, _, _attrs, _els}) ->
+    {Value, Units, Name} =
+       decode_stats_query_stat_attrs(_attrs, undefined,
+                                     undefined, undefined),
+    Error = decode_stats_query_stat_els(_els, []),
+    {stat, Name, Units, Value, Error}.
+
+decode_stats_query_stat_els([{xmlel, <<"error">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Error) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_stats_query_stat_els(_els,
+                                     [decode_stats_query_stat_error(_el)
+                                      | Error]);
+      _ -> decode_stats_query_stat_els(_els, Error)
+    end;
+decode_stats_query_stat_els([_ | _els], Error) ->
+    decode_stats_query_stat_els(_els, Error);
+decode_stats_query_stat_els([], Error) ->
+    lists:reverse(Error).
+
+decode_stats_query_stat_attrs([{<<"value">>, _val}
+                              | _attrs],
+                             _Value, Units, Name) ->
+    decode_stats_query_stat_attrs(_attrs, _val, Units,
+                                 Name);
+decode_stats_query_stat_attrs([{<<"units">>, _val}
+                              | _attrs],
+                             Value, _Units, Name) ->
+    decode_stats_query_stat_attrs(_attrs, Value, _val,
+                                 Name);
+decode_stats_query_stat_attrs([{<<"name">>, _val}
+                              | _attrs],
+                             Value, Units, _Name) ->
+    decode_stats_query_stat_attrs(_attrs, Value, Units,
+                                 _val);
+decode_stats_query_stat_attrs([_ | _attrs], Value,
+                             Units, Name) ->
+    decode_stats_query_stat_attrs(_attrs, Value, Units,
+                                 Name);
+decode_stats_query_stat_attrs([], Value, Units, Name) ->
+    {decode_stats_query_stat_value(Value),
+     decode_stats_query_stat_units(Units),
+     decode_stats_query_stat_name(Name)}.
+
+encode_stats_query_stat([], _acc) -> _acc;
+encode_stats_query_stat([{stat, Name, Units, Value,
+                         Error}
+                        | _tail],
+                       _acc) ->
+    _els = encode_stats_query_stat_error(Error, []),
+    _attrs = encode_stats_query_stat_name(Name,
+                                         encode_stats_query_stat_units(Units,
+                                                                       encode_stats_query_stat_value(Value,
+                                                                                                     []))),
+    encode_stats_query_stat(_tail,
+                           [{xmlel, <<"stat">>, _attrs, _els} | _acc]).
+
+decode_stats_query_stat_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>, <<"stat">>,
+                 <<>>});
+decode_stats_query_stat_name(_val) -> _val.
+
+encode_stats_query_stat_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_stats_query_stat_units(undefined) -> undefined;
+decode_stats_query_stat_units(_val) -> _val.
+
+encode_stats_query_stat_units(undefined, _acc) -> _acc;
+encode_stats_query_stat_units(_val, _acc) ->
+    [{<<"units">>, _val} | _acc].
+
+decode_stats_query_stat_value(undefined) -> undefined;
+decode_stats_query_stat_value(_val) -> _val.
+
+encode_stats_query_stat_value(undefined, _acc) -> _acc;
+encode_stats_query_stat_value(_val, _acc) ->
+    [{<<"value">>, _val} | _acc].
+
+decode_stats_query_stat_error({xmlel, _, _attrs,
+                              _els}) ->
+    Code = decode_stats_query_stat_error_attrs(_attrs,
+                                              undefined),
+    Cdata = decode_stats_query_stat_error_els(_els, <<>>),
+    {Code, Cdata}.
+
+decode_stats_query_stat_error_els([{xmlcdata, _data}
+                                  | _els],
+                                 Cdata) ->
+    decode_stats_query_stat_error_els(_els,
+                                     <<Cdata/binary, _data/binary>>);
+decode_stats_query_stat_error_els([_ | _els], Cdata) ->
+    decode_stats_query_stat_error_els(_els, Cdata);
+decode_stats_query_stat_error_els([], Cdata) ->
+    decode_stats_query_stat_error_cdata(Cdata).
+
+decode_stats_query_stat_error_attrs([{<<"code">>, _val}
+                                    | _attrs],
+                                   _Code) ->
+    decode_stats_query_stat_error_attrs(_attrs, _val);
+decode_stats_query_stat_error_attrs([_ | _attrs],
+                                   Code) ->
+    decode_stats_query_stat_error_attrs(_attrs, Code);
+decode_stats_query_stat_error_attrs([], Code) ->
+    decode_stats_query_stat_error_code(Code).
+
+encode_stats_query_stat_error([], _acc) -> _acc;
+encode_stats_query_stat_error([{Code, Cdata} | _tail],
+                             _acc) ->
+    _els = encode_stats_query_stat_error_cdata(Cdata, []),
+    _attrs = encode_stats_query_stat_error_code(Code, []),
+    encode_stats_query_stat_error(_tail,
+                                 [{xmlel, <<"error">>, _attrs, _els} | _acc]).
+
+decode_stats_query_stat_error_code(undefined) ->
+    erlang:error({missing_attr, <<"code">>, <<"error">>,
+                 <<>>});
+decode_stats_query_stat_error_code(_val) ->
+    case catch xml_gen:dec_int(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"code">>, <<"error">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_stats_query_stat_error_code(_val, _acc) ->
+    [{<<"code">>, xml_gen:enc_int(_val)} | _acc].
+
+decode_stats_query_stat_error_cdata(<<>>) -> undefined;
+decode_stats_query_stat_error_cdata(_val) -> _val.
+
+encode_stats_query_stat_error_cdata(undefined, _acc) ->
+    _acc;
+encode_stats_query_stat_error_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_iq_iq({xmlel, _, _attrs, _els}) ->
+    {To, From, Lang, Type, Id} = decode_iq_iq_attrs(_attrs,
+                                                   undefined, undefined,
+                                                   undefined, undefined,
+                                                   undefined),
+    {__Els, Error} = decode_iq_iq_els(_els, [], undefined),
+    {iq, Id, Type, Lang, From, To, Error, __Els}.
+
+decode_iq_iq_els([{xmlel, <<"error">>, _attrs, _} = _el
+                 | _els],
+                __Els, Error) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_iq_iq_els(_els, __Els, decode_error_error(_el));
+      _ ->
+         decode_iq_iq_els(_els, [decode(_el) | __Els], Error)
+    end;
+decode_iq_iq_els([{xmlel, _, _, _} = _el | _els], __Els,
+                Error) ->
+    decode_iq_iq_els(_els, [decode(_el) | __Els], Error);
+decode_iq_iq_els([_ | _els], __Els, Error) ->
+    decode_iq_iq_els(_els, __Els, Error);
+decode_iq_iq_els([], __Els, Error) ->
+    {lists:reverse(__Els), Error}.
+
+decode_iq_iq_attrs([{<<"to">>, _val} | _attrs], _To,
+                  From, Lang, Type, Id) ->
+    decode_iq_iq_attrs(_attrs, _val, From, Lang, Type, Id);
+decode_iq_iq_attrs([{<<"from">>, _val} | _attrs], To,
+                  _From, Lang, Type, Id) ->
+    decode_iq_iq_attrs(_attrs, To, _val, Lang, Type, Id);
+decode_iq_iq_attrs([{<<"xml:lang">>, _val} | _attrs],
+                  To, From, _Lang, Type, Id) ->
+    decode_iq_iq_attrs(_attrs, To, From, _val, Type, Id);
+decode_iq_iq_attrs([{<<"type">>, _val} | _attrs], To,
+                  From, Lang, _Type, Id) ->
+    decode_iq_iq_attrs(_attrs, To, From, Lang, _val, Id);
+decode_iq_iq_attrs([{<<"id">>, _val} | _attrs], To,
+                  From, Lang, Type, _Id) ->
+    decode_iq_iq_attrs(_attrs, To, From, Lang, Type, _val);
+decode_iq_iq_attrs([_ | _attrs], To, From, Lang, Type,
+                  Id) ->
+    decode_iq_iq_attrs(_attrs, To, From, Lang, Type, Id);
+decode_iq_iq_attrs([], To, From, Lang, Type, Id) ->
+    {decode_iq_iq_to(To), decode_iq_iq_from(From),
+     'decode_iq_iq_xml:lang'(Lang), decode_iq_iq_type(Type),
+     decode_iq_iq_id(Id)}.
+
+encode_iq_iq(undefined, _acc) -> _acc;
+encode_iq_iq({iq, Id, Type, Lang, From, To, Error,
+             __Els},
+            _acc) ->
+    _els = encode_error_error(Error,
+                             [encode(_subel) || _subel <- __Els] ++ []),
+    _attrs = encode_iq_iq_id(Id,
+                            encode_iq_iq_type(Type,
+                                              'encode_iq_iq_xml:lang'(Lang,
+                                                                      encode_iq_iq_from(From,
+                                                                                        encode_iq_iq_to(To,
+                                                                                                        []))))),
+    [{xmlel, <<"iq">>, _attrs, _els} | _acc].
+
+decode_iq_iq_id(undefined) ->
+    erlang:error({missing_attr, <<"id">>, <<"iq">>, <<>>});
+decode_iq_iq_id(_val) -> _val.
+
+encode_iq_iq_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
+
+decode_iq_iq_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"iq">>,
+                 <<>>});
+decode_iq_iq_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [get, set, result, error])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"iq">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_iq_iq_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_iq_iq_from(undefined) -> undefined;
+decode_iq_iq_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"iq">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_iq_iq_from(undefined, _acc) -> _acc;
+encode_iq_iq_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
+
+decode_iq_iq_to(undefined) -> undefined;
+decode_iq_iq_to(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"to">>, <<"iq">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_iq_iq_to(undefined, _acc) -> _acc;
+encode_iq_iq_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
+
+'decode_iq_iq_xml:lang'(undefined) -> undefined;
+'decode_iq_iq_xml:lang'(_val) -> _val.
+
+'encode_iq_iq_xml:lang'(undefined, _acc) -> _acc;
+'encode_iq_iq_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_message_message({xmlel, _, _attrs, _els}) ->
+    {To, From, Lang, Type, Id} =
+       decode_message_message_attrs(_attrs, undefined,
+                                    undefined, undefined, undefined,
+                                    undefined),
+    {__Els, Error, Thread, Body, Subject} =
+       decode_message_message_els(_els, [], undefined,
+                                  undefined, [], []),
+    {message, Id, Type, Lang, From, To, Subject, Body,
+     Thread, Error, __Els}.
+
+decode_message_message_els([{xmlel, <<"error">>, _attrs,
+                            _} =
+                               _el
+                           | _els],
+                          __Els, Error, Thread, Body, Subject) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_message_message_els(_els, __Els,
+                                    decode_error_error(_el), Thread, Body,
+                                    Subject);
+      _ ->
+         decode_message_message_els(_els, [decode(_el) | __Els],
+                                    Error, Thread, Body, Subject)
+    end;
+decode_message_message_els([{xmlel, <<"thread">>,
+                            _attrs, _} =
+                               _el
+                           | _els],
+                          __Els, Error, Thread, Body, Subject) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_message_message_els(_els, __Els, Error,
+                                    decode_message_message_thread(_el), Body,
+                                    Subject);
+      _ ->
+         decode_message_message_els(_els, [decode(_el) | __Els],
+                                    Error, Thread, Body, Subject)
+    end;
+decode_message_message_els([{xmlel, <<"body">>, _attrs,
+                            _} =
+                               _el
+                           | _els],
+                          __Els, Error, Thread, Body, Subject) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_message_message_els(_els, __Els, Error, Thread,
+                                    [decode_message_message_body(_el) | Body],
+                                    Subject);
+      _ ->
+         decode_message_message_els(_els, [decode(_el) | __Els],
+                                    Error, Thread, Body, Subject)
+    end;
+decode_message_message_els([{xmlel, <<"subject">>,
+                            _attrs, _} =
+                               _el
+                           | _els],
+                          __Els, Error, Thread, Body, Subject) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_message_message_els(_els, __Els, Error, Thread,
+                                    Body,
+                                    [decode_message_message_subject(_el)
+                                     | Subject]);
+      _ ->
+         decode_message_message_els(_els, [decode(_el) | __Els],
+                                    Error, Thread, Body, Subject)
+    end;
+decode_message_message_els([{xmlel, _, _, _} = _el
+                           | _els],
+                          __Els, Error, Thread, Body, Subject) ->
+    decode_message_message_els(_els, [decode(_el) | __Els],
+                              Error, Thread, Body, Subject);
+decode_message_message_els([_ | _els], __Els, Error,
+                          Thread, Body, Subject) ->
+    decode_message_message_els(_els, __Els, Error, Thread,
+                              Body, Subject);
+decode_message_message_els([], __Els, Error, Thread,
+                          Body, Subject) ->
+    {lists:reverse(__Els), Error, Thread,
+     lists:reverse(Body), lists:reverse(Subject)}.
+
+decode_message_message_attrs([{<<"to">>, _val}
+                             | _attrs],
+                            _To, From, Lang, Type, Id) ->
+    decode_message_message_attrs(_attrs, _val, From, Lang,
+                                Type, Id);
+decode_message_message_attrs([{<<"from">>, _val}
+                             | _attrs],
+                            To, _From, Lang, Type, Id) ->
+    decode_message_message_attrs(_attrs, To, _val, Lang,
+                                Type, Id);
+decode_message_message_attrs([{<<"xml:lang">>, _val}
+                             | _attrs],
+                            To, From, _Lang, Type, Id) ->
+    decode_message_message_attrs(_attrs, To, From, _val,
+                                Type, Id);
+decode_message_message_attrs([{<<"type">>, _val}
+                             | _attrs],
+                            To, From, Lang, _Type, Id) ->
+    decode_message_message_attrs(_attrs, To, From, Lang,
+                                _val, Id);
+decode_message_message_attrs([{<<"id">>, _val}
+                             | _attrs],
+                            To, From, Lang, Type, _Id) ->
+    decode_message_message_attrs(_attrs, To, From, Lang,
+                                Type, _val);
+decode_message_message_attrs([_ | _attrs], To, From,
+                            Lang, Type, Id) ->
+    decode_message_message_attrs(_attrs, To, From, Lang,
+                                Type, Id);
+decode_message_message_attrs([], To, From, Lang, Type,
+                            Id) ->
+    {decode_message_message_to(To),
+     decode_message_message_from(From),
+     'decode_message_message_xml:lang'(Lang),
+     decode_message_message_type(Type),
+     decode_message_message_id(Id)}.
+
+encode_message_message(undefined, _acc) -> _acc;
+encode_message_message({message, Id, Type, Lang, From,
+                       To, Subject, Body, Thread, Error, __Els},
+                      _acc) ->
+    _els = encode_message_message_subject(Subject,
+                                         encode_message_message_body(Body,
+                                                                     encode_message_message_thread(Thread,
+                                                                                                   encode_error_error(Error,
+                                                                                                                      [encode(_subel)
+                                                                                                                       || _subel
+                                                                                                                              <- __Els]
+                                                                                                                        ++
+                                                                                                                        [])))),
+    _attrs = encode_message_message_id(Id,
+                                      encode_message_message_type(Type,
+                                                                  'encode_message_message_xml:lang'(Lang,
+                                                                                                    encode_message_message_from(From,
+                                                                                                                                encode_message_message_to(To,
+                                                                                                                                                          []))))),
+    [{xmlel, <<"message">>, _attrs, _els} | _acc].
+
+decode_message_message_id(undefined) -> undefined;
+decode_message_message_id(_val) -> _val.
+
+encode_message_message_id(undefined, _acc) -> _acc;
+encode_message_message_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
+
+decode_message_message_type(undefined) -> normal;
+decode_message_message_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [chat, normal, groupchat, headline, error])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"message">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_message_message_type(normal, _acc) -> _acc;
+encode_message_message_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_message_message_from(undefined) -> undefined;
+decode_message_message_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"message">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_message_message_from(undefined, _acc) -> _acc;
+encode_message_message_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
+
+decode_message_message_to(undefined) -> undefined;
+decode_message_message_to(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"to">>, <<"message">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_message_message_to(undefined, _acc) -> _acc;
+encode_message_message_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
+
+'decode_message_message_xml:lang'(undefined) ->
+    undefined;
+'decode_message_message_xml:lang'(_val) -> _val.
+
+'encode_message_message_xml:lang'(undefined, _acc) ->
+    _acc;
+'encode_message_message_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_message_message_thread({xmlel, _, _attrs,
+                              _els}) ->
+    Cdata = decode_message_message_thread_els(_els, <<>>),
+    Cdata.
+
+decode_message_message_thread_els([{xmlcdata, _data}
+                                  | _els],
+                                 Cdata) ->
+    decode_message_message_thread_els(_els,
+                                     <<Cdata/binary, _data/binary>>);
+decode_message_message_thread_els([_ | _els], Cdata) ->
+    decode_message_message_thread_els(_els, Cdata);
+decode_message_message_thread_els([], Cdata) ->
+    decode_message_message_thread_cdata(Cdata).
+
+encode_message_message_thread(undefined, _acc) -> _acc;
+encode_message_message_thread(Cdata, _acc) ->
+    _els = encode_message_message_thread_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"thread">>, _attrs, _els} | _acc].
+
+decode_message_message_thread_cdata(<<>>) -> undefined;
+decode_message_message_thread_cdata(_val) -> _val.
+
+encode_message_message_thread_cdata(undefined, _acc) ->
+    _acc;
+encode_message_message_thread_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_message_message_body({xmlel, _, _attrs, _els}) ->
+    Body_lang = decode_message_message_body_attrs(_attrs,
+                                                 undefined),
+    Cdata = decode_message_message_body_els(_els, <<>>),
+    {Body_lang, Cdata}.
+
+decode_message_message_body_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_message_message_body_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_message_message_body_els([_ | _els], Cdata) ->
+    decode_message_message_body_els(_els, Cdata);
+decode_message_message_body_els([], Cdata) ->
+    decode_message_message_body_cdata(Cdata).
+
+decode_message_message_body_attrs([{<<"xml:lang">>,
+                                   _val}
+                                  | _attrs],
+                                 _Body_lang) ->
+    decode_message_message_body_attrs(_attrs, _val);
+decode_message_message_body_attrs([_ | _attrs],
+                                 Body_lang) ->
+    decode_message_message_body_attrs(_attrs, Body_lang);
+decode_message_message_body_attrs([], Body_lang) ->
+    'decode_message_message_body_xml:lang'(Body_lang).
+
+encode_message_message_body([], _acc) -> _acc;
+encode_message_message_body([{Body_lang, Cdata}
+                            | _tail],
+                           _acc) ->
+    _els = encode_message_message_body_cdata(Cdata, []),
+    _attrs =
+       'encode_message_message_body_xml:lang'(Body_lang, []),
+    encode_message_message_body(_tail,
+                               [{xmlel, <<"body">>, _attrs, _els} | _acc]).
+
+'decode_message_message_body_xml:lang'(undefined) ->
+    undefined;
+'decode_message_message_body_xml:lang'(_val) -> _val.
+
+'encode_message_message_body_xml:lang'(undefined,
+                                      _acc) ->
+    _acc;
+'encode_message_message_body_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_message_message_body_cdata(<<>>) -> undefined;
+decode_message_message_body_cdata(_val) -> _val.
+
+encode_message_message_body_cdata(undefined, _acc) ->
+    _acc;
+encode_message_message_body_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_message_message_subject({xmlel, _, _attrs,
+                               _els}) ->
+    Subject_lang =
+       decode_message_message_subject_attrs(_attrs, undefined),
+    Cdata = decode_message_message_subject_els(_els, <<>>),
+    {Subject_lang, Cdata}.
+
+decode_message_message_subject_els([{xmlcdata, _data}
+                                   | _els],
+                                  Cdata) ->
+    decode_message_message_subject_els(_els,
+                                      <<Cdata/binary, _data/binary>>);
+decode_message_message_subject_els([_ | _els], Cdata) ->
+    decode_message_message_subject_els(_els, Cdata);
+decode_message_message_subject_els([], Cdata) ->
+    decode_message_message_subject_cdata(Cdata).
+
+decode_message_message_subject_attrs([{<<"xml:lang">>,
+                                      _val}
+                                     | _attrs],
+                                    _Subject_lang) ->
+    decode_message_message_subject_attrs(_attrs, _val);
+decode_message_message_subject_attrs([_ | _attrs],
+                                    Subject_lang) ->
+    decode_message_message_subject_attrs(_attrs,
+                                        Subject_lang);
+decode_message_message_subject_attrs([],
+                                    Subject_lang) ->
+    'decode_message_message_subject_xml:lang'(Subject_lang).
+
+encode_message_message_subject([], _acc) -> _acc;
+encode_message_message_subject([{Subject_lang, Cdata}
+                               | _tail],
+                              _acc) ->
+    _els = encode_message_message_subject_cdata(Cdata, []),
+    _attrs =
+       'encode_message_message_subject_xml:lang'(Subject_lang,
+                                                 []),
+    encode_message_message_subject(_tail,
+                                  [{xmlel, <<"subject">>, _attrs, _els}
+                                   | _acc]).
+
+'decode_message_message_subject_xml:lang'(undefined) ->
+    undefined;
+'decode_message_message_subject_xml:lang'(_val) -> _val.
+
+'encode_message_message_subject_xml:lang'(undefined,
+                                         _acc) ->
+    _acc;
+'encode_message_message_subject_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_message_message_subject_cdata(<<>>) -> undefined;
+decode_message_message_subject_cdata(_val) -> _val.
+
+encode_message_message_subject_cdata(undefined, _acc) ->
+    _acc;
+encode_message_message_subject_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_presence_presence({xmlel, _, _attrs, _els}) ->
+    {To, From, Lang, Type, Id} =
+       decode_presence_presence_attrs(_attrs, undefined,
+                                      undefined, undefined, undefined,
+                                      undefined),
+    {__Els, Error, Priority, Status, Show} =
+       decode_presence_presence_els(_els, [], undefined,
+                                    undefined, [], undefined),
+    {presence, Id, Type, Lang, From, To, Show, Status,
+     Priority, Error, __Els}.
+
+decode_presence_presence_els([{xmlel, <<"error">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            __Els, Error, Priority, Status, Show) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_presence_presence_els(_els, __Els,
+                                      decode_error_error(_el), Priority,
+                                      Status, Show);
+      _ ->
+         decode_presence_presence_els(_els,
+                                      [decode(_el) | __Els], Error, Priority,
+                                      Status, Show)
+    end;
+decode_presence_presence_els([{xmlel, <<"priority">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            __Els, Error, Priority, Status, Show) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_presence_presence_els(_els, __Els, Error,
+                                      decode_presence_presence_priority(_el),
+                                      Status, Show);
+      _ ->
+         decode_presence_presence_els(_els,
+                                      [decode(_el) | __Els], Error, Priority,
+                                      Status, Show)
+    end;
+decode_presence_presence_els([{xmlel, <<"status">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            __Els, Error, Priority, Status, Show) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_presence_presence_els(_els, __Els, Error,
+                                      Priority,
+                                      [decode_presence_presence_status(_el)
+                                       | Status],
+                                      Show);
+      _ ->
+         decode_presence_presence_els(_els,
+                                      [decode(_el) | __Els], Error, Priority,
+                                      Status, Show)
+    end;
+decode_presence_presence_els([{xmlel, <<"show">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            __Els, Error, Priority, Status, Show) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_presence_presence_els(_els, __Els, Error,
+                                      Priority, Status,
+                                      decode_presence_presence_show(_el));
+      _ ->
+         decode_presence_presence_els(_els,
+                                      [decode(_el) | __Els], Error, Priority,
+                                      Status, Show)
+    end;
+decode_presence_presence_els([{xmlel, _, _, _} = _el
+                             | _els],
+                            __Els, Error, Priority, Status, Show) ->
+    decode_presence_presence_els(_els,
+                                [decode(_el) | __Els], Error, Priority, Status,
+                                Show);
+decode_presence_presence_els([_ | _els], __Els, Error,
+                            Priority, Status, Show) ->
+    decode_presence_presence_els(_els, __Els, Error,
+                                Priority, Status, Show);
+decode_presence_presence_els([], __Els, Error, Priority,
+                            Status, Show) ->
+    {lists:reverse(__Els), Error, Priority,
+     lists:reverse(Status), Show}.
+
+decode_presence_presence_attrs([{<<"to">>, _val}
+                               | _attrs],
+                              _To, From, Lang, Type, Id) ->
+    decode_presence_presence_attrs(_attrs, _val, From, Lang,
+                                  Type, Id);
+decode_presence_presence_attrs([{<<"from">>, _val}
+                               | _attrs],
+                              To, _From, Lang, Type, Id) ->
+    decode_presence_presence_attrs(_attrs, To, _val, Lang,
+                                  Type, Id);
+decode_presence_presence_attrs([{<<"xml:lang">>, _val}
+                               | _attrs],
+                              To, From, _Lang, Type, Id) ->
+    decode_presence_presence_attrs(_attrs, To, From, _val,
+                                  Type, Id);
+decode_presence_presence_attrs([{<<"type">>, _val}
+                               | _attrs],
+                              To, From, Lang, _Type, Id) ->
+    decode_presence_presence_attrs(_attrs, To, From, Lang,
+                                  _val, Id);
+decode_presence_presence_attrs([{<<"id">>, _val}
+                               | _attrs],
+                              To, From, Lang, Type, _Id) ->
+    decode_presence_presence_attrs(_attrs, To, From, Lang,
+                                  Type, _val);
+decode_presence_presence_attrs([_ | _attrs], To, From,
+                              Lang, Type, Id) ->
+    decode_presence_presence_attrs(_attrs, To, From, Lang,
+                                  Type, Id);
+decode_presence_presence_attrs([], To, From, Lang, Type,
+                              Id) ->
+    {decode_presence_presence_to(To),
+     decode_presence_presence_from(From),
+     'decode_presence_presence_xml:lang'(Lang),
+     decode_presence_presence_type(Type),
+     decode_presence_presence_id(Id)}.
+
+encode_presence_presence(undefined, _acc) -> _acc;
+encode_presence_presence({presence, Id, Type, Lang,
+                         From, To, Show, Status, Priority, Error, __Els},
+                        _acc) ->
+    _els = encode_presence_presence_show(Show,
+                                        encode_presence_presence_status(Status,
+                                                                        encode_presence_presence_priority(Priority,
+                                                                                                          encode_error_error(Error,
+                                                                                                                             [encode(_subel)
+                                                                                                                              || _subel
+                                                                                                                                     <- __Els]
+                                                                                                                               ++
+                                                                                                                               [])))),
+    _attrs = encode_presence_presence_id(Id,
+                                        encode_presence_presence_type(Type,
+                                                                      'encode_presence_presence_xml:lang'(Lang,
+                                                                                                          encode_presence_presence_from(From,
+                                                                                                                                        encode_presence_presence_to(To,
+                                                                                                                                                                    []))))),
+    [{xmlel, <<"presence">>, _attrs, _els} | _acc].
+
+decode_presence_presence_id(undefined) -> undefined;
+decode_presence_presence_id(_val) -> _val.
+
+encode_presence_presence_id(undefined, _acc) -> _acc;
+encode_presence_presence_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
+
+decode_presence_presence_type(undefined) -> undefined;
+decode_presence_presence_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [unavailable, subscribe, subscribed,
+                                unsubscribe, unsubscribed, probe, error])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>,
+                       <<"presence">>, <<>>});
+      _res -> _res
+    end.
+
+encode_presence_presence_type(undefined, _acc) -> _acc;
+encode_presence_presence_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_presence_presence_from(undefined) -> undefined;
+decode_presence_presence_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>,
+                       <<"presence">>, <<>>});
+      _res -> _res
+    end.
+
+encode_presence_presence_from(undefined, _acc) -> _acc;
+encode_presence_presence_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
+
+decode_presence_presence_to(undefined) -> undefined;
+decode_presence_presence_to(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"to">>, <<"presence">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_presence_presence_to(undefined, _acc) -> _acc;
+encode_presence_presence_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
+
+'decode_presence_presence_xml:lang'(undefined) ->
+    undefined;
+'decode_presence_presence_xml:lang'(_val) -> _val.
+
+'encode_presence_presence_xml:lang'(undefined, _acc) ->
+    _acc;
+'encode_presence_presence_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_presence_presence_priority({xmlel, _, _attrs,
+                                  _els}) ->
+    Cdata = decode_presence_presence_priority_els(_els,
+                                                 <<>>),
+    Cdata.
+
+decode_presence_presence_priority_els([{xmlcdata, _data}
+                                      | _els],
+                                     Cdata) ->
+    decode_presence_presence_priority_els(_els,
+                                         <<Cdata/binary, _data/binary>>);
+decode_presence_presence_priority_els([_ | _els],
+                                     Cdata) ->
+    decode_presence_presence_priority_els(_els, Cdata);
+decode_presence_presence_priority_els([], Cdata) ->
+    decode_presence_presence_priority_cdata(Cdata).
+
+encode_presence_presence_priority(undefined, _acc) ->
+    _acc;
+encode_presence_presence_priority(Cdata, _acc) ->
+    _els = encode_presence_presence_priority_cdata(Cdata,
+                                                  []),
+    _attrs = [],
+    [{xmlel, <<"priority">>, _attrs, _els} | _acc].
+
+decode_presence_presence_priority_cdata(<<>>) ->
+    undefined;
+decode_presence_presence_priority_cdata(_val) ->
+    case catch xml_gen:dec_int(_val, -128, 127) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"priority">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_presence_presence_priority_cdata(undefined,
+                                       _acc) ->
+    _acc;
+encode_presence_presence_priority_cdata(_val, _acc) ->
+    [{xmlcdata, xml_gen:enc_int(_val)} | _acc].
+
+decode_presence_presence_status({xmlel, _, _attrs,
+                                _els}) ->
+    Status_lang =
+       decode_presence_presence_status_attrs(_attrs,
+                                             undefined),
+    Cdata = decode_presence_presence_status_els(_els, <<>>),
+    {Status_lang, Cdata}.
+
+decode_presence_presence_status_els([{xmlcdata, _data}
+                                    | _els],
+                                   Cdata) ->
+    decode_presence_presence_status_els(_els,
+                                       <<Cdata/binary, _data/binary>>);
+decode_presence_presence_status_els([_ | _els],
+                                   Cdata) ->
+    decode_presence_presence_status_els(_els, Cdata);
+decode_presence_presence_status_els([], Cdata) ->
+    decode_presence_presence_status_cdata(Cdata).
+
+decode_presence_presence_status_attrs([{<<"xml:lang">>,
+                                       _val}
+                                      | _attrs],
+                                     _Status_lang) ->
+    decode_presence_presence_status_attrs(_attrs, _val);
+decode_presence_presence_status_attrs([_ | _attrs],
+                                     Status_lang) ->
+    decode_presence_presence_status_attrs(_attrs,
+                                         Status_lang);
+decode_presence_presence_status_attrs([],
+                                     Status_lang) ->
+    'decode_presence_presence_status_xml:lang'(Status_lang).
+
+encode_presence_presence_status([], _acc) -> _acc;
+encode_presence_presence_status([{Status_lang, Cdata}
+                                | _tail],
+                               _acc) ->
+    _els = encode_presence_presence_status_cdata(Cdata, []),
+    _attrs =
+       'encode_presence_presence_status_xml:lang'(Status_lang,
+                                                  []),
+    encode_presence_presence_status(_tail,
+                                   [{xmlel, <<"status">>, _attrs, _els}
+                                    | _acc]).
+
+'decode_presence_presence_status_xml:lang'(undefined) ->
+    undefined;
+'decode_presence_presence_status_xml:lang'(_val) ->
+    _val.
+
+'encode_presence_presence_status_xml:lang'(undefined,
+                                          _acc) ->
+    _acc;
+'encode_presence_presence_status_xml:lang'(_val,
+                                          _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_presence_presence_status_cdata(<<>>) ->
+    undefined;
+decode_presence_presence_status_cdata(_val) -> _val.
+
+encode_presence_presence_status_cdata(undefined,
+                                     _acc) ->
+    _acc;
+encode_presence_presence_status_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_presence_presence_show({xmlel, _, _attrs,
+                              _els}) ->
+    Cdata = decode_presence_presence_show_els(_els, <<>>),
+    Cdata.
+
+decode_presence_presence_show_els([{xmlcdata, _data}
+                                  | _els],
+                                 Cdata) ->
+    decode_presence_presence_show_els(_els,
+                                     <<Cdata/binary, _data/binary>>);
+decode_presence_presence_show_els([_ | _els], Cdata) ->
+    decode_presence_presence_show_els(_els, Cdata);
+decode_presence_presence_show_els([], Cdata) ->
+    decode_presence_presence_show_cdata(Cdata).
+
+encode_presence_presence_show(undefined, _acc) -> _acc;
+encode_presence_presence_show(Cdata, _acc) ->
+    _els = encode_presence_presence_show_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"show">>, _attrs, _els} | _acc].
+
+decode_presence_presence_show_cdata(<<>>) -> undefined;
+decode_presence_presence_show_cdata(_val) ->
+    case catch xml_gen:dec_enum(_val, [away, chat, dnd, xa])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"show">>, <<>>});
+      _res -> _res
+    end.
+
+encode_presence_presence_show_cdata(undefined, _acc) ->
+    _acc;
+encode_presence_presence_show_cdata(_val, _acc) ->
+    [{xmlcdata, xml_gen:enc_enum(_val)} | _acc].
+
+decode_error_error({xmlel, _, _attrs, _els}) ->
+    {By, Error_type} = decode_error_error_attrs(_attrs,
+                                               undefined, undefined),
+    {Text, Reason} = decode_error_error_els(_els, undefined,
+                                           undefined),
+    {error, Error_type, By, Reason, Text}.
+
+decode_error_error_els([{xmlel, <<"text">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els,
+                                decode_error_error_text(_el), Reason);
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"unexpected-request">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_unexpected-request'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"undefined-condition">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_undefined-condition'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"subscription-required">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_subscription-required'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"service-unavailable">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_service-unavailable'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"resource-constraint">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_resource-constraint'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"remote-server-timeout">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_remote-server-timeout'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"remote-server-not-found">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_remote-server-not-found'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"registration-required">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_registration-required'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"redirect">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                decode_error_error_redirect(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"recipient-unavailable">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_recipient-unavailable'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"policy-violation">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_policy-violation'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"not-authorized">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_not-authorized'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"not-allowed">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_not-allowed'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"not-acceptable">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_not-acceptable'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"jid-malformed">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_jid-malformed'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"item-not-found">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_item-not-found'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"internal-server-error">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_internal-server-error'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"gone">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                decode_error_error_gone(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"forbidden">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                decode_error_error_forbidden(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel,
+                        <<"feature-not-implemented">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_feature-not-implemented'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"conflict">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                decode_error_error_conflict(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([{xmlel, <<"bad-request">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+         decode_error_error_els(_els, Text,
+                                'decode_error_error_bad-request'(_el));
+      _ -> decode_error_error_els(_els, Text, Reason)
+    end;
+decode_error_error_els([_ | _els], Text, Reason) ->
+    decode_error_error_els(_els, Text, Reason);
+decode_error_error_els([], Text, Reason) ->
+    {Text, Reason}.
+
+decode_error_error_attrs([{<<"by">>, _val} | _attrs],
+                        _By, Error_type) ->
+    decode_error_error_attrs(_attrs, _val, Error_type);
+decode_error_error_attrs([{<<"type">>, _val} | _attrs],
+                        By, _Error_type) ->
+    decode_error_error_attrs(_attrs, By, _val);
+decode_error_error_attrs([_ | _attrs], By,
+                        Error_type) ->
+    decode_error_error_attrs(_attrs, By, Error_type);
+decode_error_error_attrs([], By, Error_type) ->
+    {decode_error_error_by(By),
+     decode_error_error_type(Error_type)}.
+
+'encode_error_error_$reason'(undefined, _acc) -> _acc;
+'encode_error_error_$reason'('unexpected-request' = _r,
+                            _acc) ->
+    'encode_error_error_unexpected-request'(_r, _acc);
+'encode_error_error_$reason'('undefined-condition' = _r,
+                            _acc) ->
+    'encode_error_error_undefined-condition'(_r, _acc);
+'encode_error_error_$reason'('subscription-required' =
+                                _r,
+                            _acc) ->
+    'encode_error_error_subscription-required'(_r, _acc);
+'encode_error_error_$reason'('service-unavailable' = _r,
+                            _acc) ->
+    'encode_error_error_service-unavailable'(_r, _acc);
+'encode_error_error_$reason'('resource-constraint' = _r,
+                            _acc) ->
+    'encode_error_error_resource-constraint'(_r, _acc);
+'encode_error_error_$reason'('remote-server-timeout' =
+                                _r,
+                            _acc) ->
+    'encode_error_error_remote-server-timeout'(_r, _acc);
+'encode_error_error_$reason'('remote-server-not-found' =
+                                _r,
+                            _acc) ->
+    'encode_error_error_remote-server-not-found'(_r, _acc);
+'encode_error_error_$reason'('registration-required' =
+                                _r,
+                            _acc) ->
+    'encode_error_error_registration-required'(_r, _acc);
+'encode_error_error_$reason'({redirect, _} = _r,
+                            _acc) ->
+    encode_error_error_redirect(_r, _acc);
+'encode_error_error_$reason'('recipient-unavailable' =
+                                _r,
+                            _acc) ->
+    'encode_error_error_recipient-unavailable'(_r, _acc);
+'encode_error_error_$reason'('policy-violation' = _r,
+                            _acc) ->
+    'encode_error_error_policy-violation'(_r, _acc);
+'encode_error_error_$reason'('not-authorized' = _r,
+                            _acc) ->
+    'encode_error_error_not-authorized'(_r, _acc);
+'encode_error_error_$reason'('not-allowed' = _r,
+                            _acc) ->
+    'encode_error_error_not-allowed'(_r, _acc);
+'encode_error_error_$reason'('not-acceptable' = _r,
+                            _acc) ->
+    'encode_error_error_not-acceptable'(_r, _acc);
+'encode_error_error_$reason'('jid-malformed' = _r,
+                            _acc) ->
+    'encode_error_error_jid-malformed'(_r, _acc);
+'encode_error_error_$reason'('item-not-found' = _r,
+                            _acc) ->
+    'encode_error_error_item-not-found'(_r, _acc);
+'encode_error_error_$reason'('internal-server-error' =
+                                _r,
+                            _acc) ->
+    'encode_error_error_internal-server-error'(_r, _acc);
+'encode_error_error_$reason'({gone, _} = _r, _acc) ->
+    encode_error_error_gone(_r, _acc);
+'encode_error_error_$reason'(forbidden = _r, _acc) ->
+    encode_error_error_forbidden(_r, _acc);
+'encode_error_error_$reason'('feature-not-implemented' =
+                                _r,
+                            _acc) ->
+    'encode_error_error_feature-not-implemented'(_r, _acc);
+'encode_error_error_$reason'(conflict = _r, _acc) ->
+    encode_error_error_conflict(_r, _acc);
+'encode_error_error_$reason'('bad-request' = _r,
+                            _acc) ->
+    'encode_error_error_bad-request'(_r, _acc).
+
+encode_error_error(undefined, _acc) -> _acc;
+encode_error_error({error, Error_type, By, Reason,
+                   Text},
+                  _acc) ->
+    _els = 'encode_error_error_$reason'(Reason,
+                                       encode_error_error_text(Text, [])),
+    _attrs = encode_error_error_type(Error_type,
+                                    encode_error_error_by(By, [])),
+    [{xmlel, <<"error">>, _attrs, _els} | _acc].
+
+decode_error_error_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"error">>,
+                 <<>>});
+decode_error_error_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [auth, cancel, continue, modify, wait])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"error">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_error_error_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_error_error_by(undefined) -> undefined;
+decode_error_error_by(_val) -> _val.
+
+encode_error_error_by(undefined, _acc) -> _acc;
+encode_error_error_by(_val, _acc) ->
+    [{<<"by">>, _val} | _acc].
+
+'decode_error_error_unexpected-request'({xmlel, _,
+                                        _attrs, _els}) ->
+    'unexpected-request'.
+
+'encode_error_error_unexpected-request'(undefined,
+                                       _acc) ->
+    _acc;
+'encode_error_error_unexpected-request'('unexpected-request',
+                                       _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"unexpected-request">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_undefined-condition'({xmlel, _,
+                                         _attrs, _els}) ->
+    'undefined-condition'.
+
+'encode_error_error_undefined-condition'(undefined,
+                                        _acc) ->
+    _acc;
+'encode_error_error_undefined-condition'('undefined-condition',
+                                        _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"undefined-condition">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_subscription-required'({xmlel, _,
+                                           _attrs, _els}) ->
+    'subscription-required'.
+
+'encode_error_error_subscription-required'(undefined,
+                                          _acc) ->
+    _acc;
+'encode_error_error_subscription-required'('subscription-required',
+                                          _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"subscription-required">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_service-unavailable'({xmlel, _,
+                                         _attrs, _els}) ->
+    'service-unavailable'.
+
+'encode_error_error_service-unavailable'(undefined,
+                                        _acc) ->
+    _acc;
+'encode_error_error_service-unavailable'('service-unavailable',
+                                        _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"service-unavailable">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_resource-constraint'({xmlel, _,
+                                         _attrs, _els}) ->
+    'resource-constraint'.
+
+'encode_error_error_resource-constraint'(undefined,
+                                        _acc) ->
+    _acc;
+'encode_error_error_resource-constraint'('resource-constraint',
+                                        _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"resource-constraint">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_remote-server-timeout'({xmlel, _,
+                                           _attrs, _els}) ->
+    'remote-server-timeout'.
+
+'encode_error_error_remote-server-timeout'(undefined,
+                                          _acc) ->
+    _acc;
+'encode_error_error_remote-server-timeout'('remote-server-timeout',
+                                          _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"remote-server-timeout">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_remote-server-not-found'({xmlel, _,
+                                             _attrs, _els}) ->
+    'remote-server-not-found'.
+
+'encode_error_error_remote-server-not-found'(undefined,
+                                            _acc) ->
+    _acc;
+'encode_error_error_remote-server-not-found'('remote-server-not-found',
+                                            _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"remote-server-not-found">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_registration-required'({xmlel, _,
+                                           _attrs, _els}) ->
+    'registration-required'.
+
+'encode_error_error_registration-required'(undefined,
+                                          _acc) ->
+    _acc;
+'encode_error_error_registration-required'('registration-required',
+                                          _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"registration-required">>, _attrs, _els}
+     | _acc].
+
+decode_error_error_redirect({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_error_error_redirect_els(_els, <<>>),
+    {redirect, Cdata}.
+
+decode_error_error_redirect_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_error_error_redirect_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_error_error_redirect_els([_ | _els], Cdata) ->
+    decode_error_error_redirect_els(_els, Cdata);
+decode_error_error_redirect_els([], Cdata) ->
+    decode_error_error_redirect_cdata(Cdata).
+
+encode_error_error_redirect(undefined, _acc) -> _acc;
+encode_error_error_redirect({redirect, Cdata}, _acc) ->
+    _els = encode_error_error_redirect_cdata(Cdata, []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"redirect">>, _attrs, _els} | _acc].
+
+decode_error_error_redirect_cdata(<<>>) -> undefined;
+decode_error_error_redirect_cdata(_val) -> _val.
+
+encode_error_error_redirect_cdata(undefined, _acc) ->
+    _acc;
+encode_error_error_redirect_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+'decode_error_error_recipient-unavailable'({xmlel, _,
+                                           _attrs, _els}) ->
+    'recipient-unavailable'.
+
+'encode_error_error_recipient-unavailable'(undefined,
+                                          _acc) ->
+    _acc;
+'encode_error_error_recipient-unavailable'('recipient-unavailable',
+                                          _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"recipient-unavailable">>, _attrs, _els}
+     | _acc].
+
+'decode_error_error_policy-violation'({xmlel, _, _attrs,
+                                      _els}) ->
+    'policy-violation'.
+
+'encode_error_error_policy-violation'(undefined,
+                                     _acc) ->
+    _acc;
+'encode_error_error_policy-violation'('policy-violation',
+                                     _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"policy-violation">>, _attrs, _els} | _acc].
+
+'decode_error_error_not-authorized'({xmlel, _, _attrs,
+                                    _els}) ->
+    'not-authorized'.
+
+'encode_error_error_not-authorized'(undefined, _acc) ->
+    _acc;
+'encode_error_error_not-authorized'('not-authorized',
+                                   _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"not-authorized">>, _attrs, _els} | _acc].
+
+'decode_error_error_not-allowed'({xmlel, _, _attrs,
+                                 _els}) ->
+    'not-allowed'.
+
+'encode_error_error_not-allowed'(undefined, _acc) ->
+    _acc;
+'encode_error_error_not-allowed'('not-allowed', _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"not-allowed">>, _attrs, _els} | _acc].
+
+'decode_error_error_not-acceptable'({xmlel, _, _attrs,
+                                    _els}) ->
+    'not-acceptable'.
+
+'encode_error_error_not-acceptable'(undefined, _acc) ->
+    _acc;
+'encode_error_error_not-acceptable'('not-acceptable',
+                                   _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"not-acceptable">>, _attrs, _els} | _acc].
+
+'decode_error_error_jid-malformed'({xmlel, _, _attrs,
+                                   _els}) ->
+    'jid-malformed'.
+
+'encode_error_error_jid-malformed'(undefined, _acc) ->
+    _acc;
+'encode_error_error_jid-malformed'('jid-malformed',
+                                  _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"jid-malformed">>, _attrs, _els} | _acc].
+
+'decode_error_error_item-not-found'({xmlel, _, _attrs,
+                                    _els}) ->
+    'item-not-found'.
+
+'encode_error_error_item-not-found'(undefined, _acc) ->
+    _acc;
+'encode_error_error_item-not-found'('item-not-found',
+                                   _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"item-not-found">>, _attrs, _els} | _acc].
+
+'decode_error_error_internal-server-error'({xmlel, _,
+                                           _attrs, _els}) ->
+    'internal-server-error'.
+
+'encode_error_error_internal-server-error'(undefined,
+                                          _acc) ->
+    _acc;
+'encode_error_error_internal-server-error'('internal-server-error',
+                                          _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"internal-server-error">>, _attrs, _els}
+     | _acc].
+
+decode_error_error_gone({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_error_error_gone_els(_els, <<>>),
+    {gone, Cdata}.
+
+decode_error_error_gone_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_error_error_gone_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_error_error_gone_els([_ | _els], Cdata) ->
+    decode_error_error_gone_els(_els, Cdata);
+decode_error_error_gone_els([], Cdata) ->
+    decode_error_error_gone_cdata(Cdata).
+
+encode_error_error_gone(undefined, _acc) -> _acc;
+encode_error_error_gone({gone, Cdata}, _acc) ->
+    _els = encode_error_error_gone_cdata(Cdata, []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"gone">>, _attrs, _els} | _acc].
+
+decode_error_error_gone_cdata(<<>>) -> undefined;
+decode_error_error_gone_cdata(_val) -> _val.
+
+encode_error_error_gone_cdata(undefined, _acc) -> _acc;
+encode_error_error_gone_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_error_error_forbidden({xmlel, _, _attrs,
+                             _els}) ->
+    forbidden.
+
+encode_error_error_forbidden(undefined, _acc) -> _acc;
+encode_error_error_forbidden(forbidden, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"forbidden">>, _attrs, _els} | _acc].
+
+'decode_error_error_feature-not-implemented'({xmlel, _,
+                                             _attrs, _els}) ->
+    'feature-not-implemented'.
+
+'encode_error_error_feature-not-implemented'(undefined,
+                                            _acc) ->
+    _acc;
+'encode_error_error_feature-not-implemented'('feature-not-implemented',
+                                            _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"feature-not-implemented">>, _attrs, _els}
+     | _acc].
+
+decode_error_error_conflict({xmlel, _, _attrs, _els}) ->
+    conflict.
+
+encode_error_error_conflict(undefined, _acc) -> _acc;
+encode_error_error_conflict(conflict, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"conflict">>, _attrs, _els} | _acc].
+
+'decode_error_error_bad-request'({xmlel, _, _attrs,
+                                 _els}) ->
+    'bad-request'.
+
+'encode_error_error_bad-request'(undefined, _acc) ->
+    _acc;
+'encode_error_error_bad-request'('bad-request', _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}],
+    [{xmlel, <<"bad-request">>, _attrs, _els} | _acc].
+
+decode_error_error_text({xmlel, _, _attrs, _els}) ->
+    Text_lang = decode_error_error_text_attrs(_attrs,
+                                             undefined),
+    Cdata = decode_error_error_text_els(_els, <<>>),
+    {Text_lang, Cdata}.
+
+decode_error_error_text_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_error_error_text_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_error_error_text_els([_ | _els], Cdata) ->
+    decode_error_error_text_els(_els, Cdata);
+decode_error_error_text_els([], Cdata) ->
+    decode_error_error_text_cdata(Cdata).
+
+decode_error_error_text_attrs([{<<"xml:lang">>, _val}
+                              | _attrs],
+                             _Text_lang) ->
+    decode_error_error_text_attrs(_attrs, _val);
+decode_error_error_text_attrs([_ | _attrs],
+                             Text_lang) ->
+    decode_error_error_text_attrs(_attrs, Text_lang);
+decode_error_error_text_attrs([], Text_lang) ->
+    'decode_error_error_text_xml:lang'(Text_lang).
+
+encode_error_error_text(undefined, _acc) -> _acc;
+encode_error_error_text({Text_lang, Cdata}, _acc) ->
+    _els = encode_error_error_text_cdata(Cdata, []),
+    _attrs = 'encode_error_error_text_xml:lang'(Text_lang,
+                                               [{<<"xmlns">>,
+                                                 <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]),
+    [{xmlel, <<"text">>, _attrs, _els} | _acc].
+
+'decode_error_error_text_xml:lang'(undefined) ->
+    undefined;
+'decode_error_error_text_xml:lang'(_val) -> _val.
+
+'encode_error_error_text_xml:lang'(undefined, _acc) ->
+    _acc;
+'encode_error_error_text_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_error_error_text_cdata(<<>>) -> undefined;
+decode_error_error_text_cdata(_val) -> _val.
+
+encode_error_error_text_cdata(undefined, _acc) -> _acc;
+encode_error_error_text_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_bind_bind({xmlel, _, _attrs, _els}) ->
+    {Resource, Jid} = decode_bind_bind_els(_els, undefined,
+                                          undefined),
+    {bind, Jid, Resource}.
+
+decode_bind_bind_els([{xmlel, <<"resource">>, _attrs,
+                      _} =
+                         _el
+                     | _els],
+                    Resource, Jid) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_bind_bind_els(_els,
+                              decode_bind_bind_resource(_el), Jid);
+      _ -> decode_bind_bind_els(_els, Resource, Jid)
+    end;
+decode_bind_bind_els([{xmlel, <<"jid">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Resource, Jid) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_bind_bind_els(_els, Resource,
+                              decode_bind_bind_jid(_el));
+      _ -> decode_bind_bind_els(_els, Resource, Jid)
+    end;
+decode_bind_bind_els([_ | _els], Resource, Jid) ->
+    decode_bind_bind_els(_els, Resource, Jid);
+decode_bind_bind_els([], Resource, Jid) ->
+    {Resource, Jid}.
+
+encode_bind_bind(undefined, _acc) -> _acc;
+encode_bind_bind({bind, Jid, Resource}, _acc) ->
+    _els = encode_bind_bind_jid(Jid,
+                               encode_bind_bind_resource(Resource, [])),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-bind">>}],
+    [{xmlel, <<"bind">>, _attrs, _els} | _acc].
+
+decode_bind_bind_resource({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_bind_bind_resource_els(_els, <<>>),
+    Cdata.
+
+decode_bind_bind_resource_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_bind_bind_resource_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_bind_bind_resource_els([_ | _els], Cdata) ->
+    decode_bind_bind_resource_els(_els, Cdata);
+decode_bind_bind_resource_els([], Cdata) ->
+    decode_bind_bind_resource_cdata(Cdata).
+
+encode_bind_bind_resource(undefined, _acc) -> _acc;
+encode_bind_bind_resource(Cdata, _acc) ->
+    _els = encode_bind_bind_resource_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"resource">>, _attrs, _els} | _acc].
+
+decode_bind_bind_resource_cdata(<<>>) -> undefined;
+decode_bind_bind_resource_cdata(_val) ->
+    case catch resourceprep(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"resource">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_bind_bind_resource_cdata(undefined, _acc) ->
+    _acc;
+encode_bind_bind_resource_cdata(_val, _acc) ->
+    [{xmlcdata, resourceprep(_val)} | _acc].
+
+decode_bind_bind_jid({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_bind_bind_jid_els(_els, <<>>), Cdata.
+
+decode_bind_bind_jid_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_bind_bind_jid_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_bind_bind_jid_els([_ | _els], Cdata) ->
+    decode_bind_bind_jid_els(_els, Cdata);
+decode_bind_bind_jid_els([], Cdata) ->
+    decode_bind_bind_jid_cdata(Cdata).
+
+encode_bind_bind_jid(undefined, _acc) -> _acc;
+encode_bind_bind_jid(Cdata, _acc) ->
+    _els = encode_bind_bind_jid_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"jid">>, _attrs, _els} | _acc].
+
+decode_bind_bind_jid_cdata(<<>>) -> undefined;
+decode_bind_bind_jid_cdata(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"jid">>, <<>>});
+      _res -> _res
+    end.
+
+encode_bind_bind_jid_cdata(undefined, _acc) -> _acc;
+encode_bind_bind_jid_cdata(_val, _acc) ->
+    [{xmlcdata, enc_jid(_val)} | _acc].
+
+decode_sasl_auth_auth({xmlel, _, _attrs, _els}) ->
+    Mechanism = decode_sasl_auth_auth_attrs(_attrs,
+                                           undefined),
+    Cdata = decode_sasl_auth_auth_els(_els, <<>>),
+    {sasl_auth, Mechanism, Cdata}.
+
+decode_sasl_auth_auth_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_sasl_auth_auth_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_sasl_auth_auth_els([_ | _els], Cdata) ->
+    decode_sasl_auth_auth_els(_els, Cdata);
+decode_sasl_auth_auth_els([], Cdata) ->
+    decode_sasl_auth_auth_cdata(Cdata).
+
+decode_sasl_auth_auth_attrs([{<<"mechanism">>, _val}
+                            | _attrs],
+                           _Mechanism) ->
+    decode_sasl_auth_auth_attrs(_attrs, _val);
+decode_sasl_auth_auth_attrs([_ | _attrs], Mechanism) ->
+    decode_sasl_auth_auth_attrs(_attrs, Mechanism);
+decode_sasl_auth_auth_attrs([], Mechanism) ->
+    decode_sasl_auth_auth_mechanism(Mechanism).
+
+encode_sasl_auth_auth(undefined, _acc) -> _acc;
+encode_sasl_auth_auth({sasl_auth, Mechanism, Cdata},
+                     _acc) ->
+    _els = encode_sasl_auth_auth_cdata(Cdata, []),
+    _attrs = encode_sasl_auth_auth_mechanism(Mechanism,
+                                            [{<<"xmlns">>,
+                                              <<"urn:ietf:params:xml:ns:xmpp-sasl">>}]),
+    [{xmlel, <<"auth">>, _attrs, _els} | _acc].
+
+decode_sasl_auth_auth_mechanism(undefined) ->
+    erlang:error({missing_attr, <<"mechanism">>, <<"auth">>,
+                 <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+decode_sasl_auth_auth_mechanism(_val) -> _val.
+
+encode_sasl_auth_auth_mechanism(_val, _acc) ->
+    [{<<"mechanism">>, _val} | _acc].
+
+decode_sasl_auth_auth_cdata(<<>>) -> undefined;
+decode_sasl_auth_auth_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"auth">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
+
+encode_sasl_auth_auth_cdata(undefined, _acc) -> _acc;
+encode_sasl_auth_auth_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
+
+decode_sasl_abort_abort({xmlel, _, _attrs, _els}) ->
+    {sasl_abort}.
+
+encode_sasl_abort_abort(undefined, _acc) -> _acc;
+encode_sasl_abort_abort({sasl_abort}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-sasl">>}],
+    [{xmlel, <<"abort">>, _attrs, _els} | _acc].
+
+decode_sasl_challenge_challenge({xmlel, _, _attrs,
+                                _els}) ->
+    Cdata = decode_sasl_challenge_challenge_els(_els, <<>>),
+    {sasl_challenge, Cdata}.
+
+decode_sasl_challenge_challenge_els([{xmlcdata, _data}
+                                    | _els],
+                                   Cdata) ->
+    decode_sasl_challenge_challenge_els(_els,
+                                       <<Cdata/binary, _data/binary>>);
+decode_sasl_challenge_challenge_els([_ | _els],
+                                   Cdata) ->
+    decode_sasl_challenge_challenge_els(_els, Cdata);
+decode_sasl_challenge_challenge_els([], Cdata) ->
+    decode_sasl_challenge_challenge_cdata(Cdata).
+
+encode_sasl_challenge_challenge(undefined, _acc) ->
+    _acc;
+encode_sasl_challenge_challenge({sasl_challenge, Cdata},
+                               _acc) ->
+    _els = encode_sasl_challenge_challenge_cdata(Cdata, []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-sasl">>}],
+    [{xmlel, <<"challenge">>, _attrs, _els} | _acc].
+
+decode_sasl_challenge_challenge_cdata(<<>>) ->
+    undefined;
+decode_sasl_challenge_challenge_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"challenge">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
+
+encode_sasl_challenge_challenge_cdata(undefined,
+                                     _acc) ->
+    _acc;
+encode_sasl_challenge_challenge_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
+
+decode_sasl_response_response({xmlel, _, _attrs,
+                              _els}) ->
+    Cdata = decode_sasl_response_response_els(_els, <<>>),
+    {sasl_response, Cdata}.
+
+decode_sasl_response_response_els([{xmlcdata, _data}
+                                  | _els],
+                                 Cdata) ->
+    decode_sasl_response_response_els(_els,
+                                     <<Cdata/binary, _data/binary>>);
+decode_sasl_response_response_els([_ | _els], Cdata) ->
+    decode_sasl_response_response_els(_els, Cdata);
+decode_sasl_response_response_els([], Cdata) ->
+    decode_sasl_response_response_cdata(Cdata).
+
+encode_sasl_response_response(undefined, _acc) -> _acc;
+encode_sasl_response_response({sasl_response, Cdata},
+                             _acc) ->
+    _els = encode_sasl_response_response_cdata(Cdata, []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-sasl">>}],
+    [{xmlel, <<"response">>, _attrs, _els} | _acc].
+
+decode_sasl_response_response_cdata(<<>>) -> undefined;
+decode_sasl_response_response_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"response">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
+
+encode_sasl_response_response_cdata(undefined, _acc) ->
+    _acc;
+encode_sasl_response_response_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
+
+decode_sasl_success_success({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_sasl_success_success_els(_els, <<>>),
+    {sasl_success, Cdata}.
+
+decode_sasl_success_success_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_sasl_success_success_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_sasl_success_success_els([_ | _els], Cdata) ->
+    decode_sasl_success_success_els(_els, Cdata);
+decode_sasl_success_success_els([], Cdata) ->
+    decode_sasl_success_success_cdata(Cdata).
+
+encode_sasl_success_success(undefined, _acc) -> _acc;
+encode_sasl_success_success({sasl_success, Cdata},
+                           _acc) ->
+    _els = encode_sasl_success_success_cdata(Cdata, []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-sasl">>}],
+    [{xmlel, <<"success">>, _attrs, _els} | _acc].
+
+decode_sasl_success_success_cdata(<<>>) -> undefined;
+decode_sasl_success_success_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"success">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
+
+encode_sasl_success_success_cdata(undefined, _acc) ->
+    _acc;
+encode_sasl_success_success_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
+
+decode_sasl_failure_failure({xmlel, _, _attrs, _els}) ->
+    {Text, Reason} = decode_sasl_failure_failure_els(_els,
+                                                    undefined, undefined),
+    {sasl_failure, Reason, Text}.
+
+decode_sasl_failure_failure_els([{xmlel, <<"text">>,
+                                 _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els,
+                                         decode_sasl_failure_failure_text(_el),
+                                         Reason);
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"temporary-auth-failure">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_temporary-auth-failure'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"not-authorized">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_not-authorized'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"mechanism-too-weak">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_mechanism-too-weak'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"malformed-request">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_malformed-request'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"invalid-mechanism">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_invalid-mechanism'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"invalid-authzid">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_invalid-authzid'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"incorrect-encoding">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_incorrect-encoding'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"encryption-required">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_encryption-required'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"credentials-expired">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_credentials-expired'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel,
+                                 <<"account-disabled">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         'decode_sasl_failure_failure_account-disabled'(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([{xmlel, <<"aborted">>,
+                                 _attrs, _} =
+                                    _el
+                                | _els],
+                               Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_failure_failure_els(_els, Text,
+                                         decode_sasl_failure_failure_aborted(_el));
+      _ -> decode_sasl_failure_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_failure_els([_ | _els], Text,
+                               Reason) ->
+    decode_sasl_failure_failure_els(_els, Text, Reason);
+decode_sasl_failure_failure_els([], Text, Reason) ->
+    {Text, Reason}.
+
+'encode_sasl_failure_failure_$reason'(undefined,
+                                     _acc) ->
+    _acc;
+'encode_sasl_failure_failure_$reason'('temporary-auth-failure' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_temporary-auth-failure'(_r,
+                                                        _acc);
+'encode_sasl_failure_failure_$reason'('not-authorized' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_not-authorized'(_r, _acc);
+'encode_sasl_failure_failure_$reason'('mechanism-too-weak' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_mechanism-too-weak'(_r,
+                                                    _acc);
+'encode_sasl_failure_failure_$reason'('malformed-request' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_malformed-request'(_r,
+                                                   _acc);
+'encode_sasl_failure_failure_$reason'('invalid-mechanism' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_invalid-mechanism'(_r,
+                                                   _acc);
+'encode_sasl_failure_failure_$reason'('invalid-authzid' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_invalid-authzid'(_r, _acc);
+'encode_sasl_failure_failure_$reason'('incorrect-encoding' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_incorrect-encoding'(_r,
+                                                    _acc);
+'encode_sasl_failure_failure_$reason'('encryption-required' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_encryption-required'(_r,
+                                                     _acc);
+'encode_sasl_failure_failure_$reason'('credentials-expired' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_credentials-expired'(_r,
+                                                     _acc);
+'encode_sasl_failure_failure_$reason'('account-disabled' =
+                                         _r,
+                                     _acc) ->
+    'encode_sasl_failure_failure_account-disabled'(_r,
+                                                  _acc);
+'encode_sasl_failure_failure_$reason'(aborted = _r,
+                                     _acc) ->
+    encode_sasl_failure_failure_aborted(_r, _acc).
+
+encode_sasl_failure_failure(undefined, _acc) -> _acc;
+encode_sasl_failure_failure({sasl_failure, Reason,
+                            Text},
+                           _acc) ->
+    _els = 'encode_sasl_failure_failure_$reason'(Reason,
+                                                encode_sasl_failure_failure_text(Text,
+                                                                                 [])),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-sasl">>}],
+    [{xmlel, <<"failure">>, _attrs, _els} | _acc].
+
+'decode_sasl_failure_failure_temporary-auth-failure'({xmlel,
+                                                     _, _attrs, _els}) ->
+    'temporary-auth-failure'.
+
+'encode_sasl_failure_failure_temporary-auth-failure'(undefined,
+                                                    _acc) ->
+    _acc;
+'encode_sasl_failure_failure_temporary-auth-failure'('temporary-auth-failure',
+                                                    _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"temporary-auth-failure">>, _attrs, _els}
+     | _acc].
+
+'decode_sasl_failure_failure_not-authorized'({xmlel, _,
+                                             _attrs, _els}) ->
+    'not-authorized'.
+
+'encode_sasl_failure_failure_not-authorized'(undefined,
+                                            _acc) ->
+    _acc;
+'encode_sasl_failure_failure_not-authorized'('not-authorized',
+                                            _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"not-authorized">>, _attrs, _els} | _acc].
+
+'decode_sasl_failure_failure_mechanism-too-weak'({xmlel,
+                                                 _, _attrs, _els}) ->
+    'mechanism-too-weak'.
+
+'encode_sasl_failure_failure_mechanism-too-weak'(undefined,
+                                                _acc) ->
+    _acc;
+'encode_sasl_failure_failure_mechanism-too-weak'('mechanism-too-weak',
+                                                _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"mechanism-too-weak">>, _attrs, _els}
+     | _acc].
+
+'decode_sasl_failure_failure_malformed-request'({xmlel,
+                                                _, _attrs, _els}) ->
+    'malformed-request'.
+
+'encode_sasl_failure_failure_malformed-request'(undefined,
+                                               _acc) ->
+    _acc;
+'encode_sasl_failure_failure_malformed-request'('malformed-request',
+                                               _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"malformed-request">>, _attrs, _els} | _acc].
+
+'decode_sasl_failure_failure_invalid-mechanism'({xmlel,
+                                                _, _attrs, _els}) ->
+    'invalid-mechanism'.
+
+'encode_sasl_failure_failure_invalid-mechanism'(undefined,
+                                               _acc) ->
+    _acc;
+'encode_sasl_failure_failure_invalid-mechanism'('invalid-mechanism',
+                                               _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"invalid-mechanism">>, _attrs, _els} | _acc].
+
+'decode_sasl_failure_failure_invalid-authzid'({xmlel, _,
+                                              _attrs, _els}) ->
+    'invalid-authzid'.
+
+'encode_sasl_failure_failure_invalid-authzid'(undefined,
+                                             _acc) ->
+    _acc;
+'encode_sasl_failure_failure_invalid-authzid'('invalid-authzid',
+                                             _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"invalid-authzid">>, _attrs, _els} | _acc].
+
+'decode_sasl_failure_failure_incorrect-encoding'({xmlel,
+                                                 _, _attrs, _els}) ->
+    'incorrect-encoding'.
+
+'encode_sasl_failure_failure_incorrect-encoding'(undefined,
+                                                _acc) ->
+    _acc;
+'encode_sasl_failure_failure_incorrect-encoding'('incorrect-encoding',
+                                                _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"incorrect-encoding">>, _attrs, _els}
+     | _acc].
+
+'decode_sasl_failure_failure_encryption-required'({xmlel,
+                                                  _, _attrs, _els}) ->
+    'encryption-required'.
+
+'encode_sasl_failure_failure_encryption-required'(undefined,
+                                                 _acc) ->
+    _acc;
+'encode_sasl_failure_failure_encryption-required'('encryption-required',
+                                                 _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"encryption-required">>, _attrs, _els}
+     | _acc].
+
+'decode_sasl_failure_failure_credentials-expired'({xmlel,
+                                                  _, _attrs, _els}) ->
+    'credentials-expired'.
+
+'encode_sasl_failure_failure_credentials-expired'(undefined,
+                                                 _acc) ->
+    _acc;
+'encode_sasl_failure_failure_credentials-expired'('credentials-expired',
+                                                 _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"credentials-expired">>, _attrs, _els}
+     | _acc].
+
+'decode_sasl_failure_failure_account-disabled'({xmlel,
+                                               _, _attrs, _els}) ->
+    'account-disabled'.
+
+'encode_sasl_failure_failure_account-disabled'(undefined,
+                                              _acc) ->
+    _acc;
+'encode_sasl_failure_failure_account-disabled'('account-disabled',
+                                              _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"account-disabled">>, _attrs, _els} | _acc].
+
+decode_sasl_failure_failure_aborted({xmlel, _, _attrs,
+                                    _els}) ->
+    aborted.
+
+encode_sasl_failure_failure_aborted(undefined, _acc) ->
+    _acc;
+encode_sasl_failure_failure_aborted(aborted, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"aborted">>, _attrs, _els} | _acc].
+
+decode_sasl_failure_failure_text({xmlel, _, _attrs,
+                                 _els}) ->
+    Text_lang =
+       decode_sasl_failure_failure_text_attrs(_attrs,
+                                              undefined),
+    Cdata = decode_sasl_failure_failure_text_els(_els,
+                                                <<>>),
+    {Text_lang, Cdata}.
+
+decode_sasl_failure_failure_text_els([{xmlcdata, _data}
+                                     | _els],
+                                    Cdata) ->
+    decode_sasl_failure_failure_text_els(_els,
+                                        <<Cdata/binary, _data/binary>>);
+decode_sasl_failure_failure_text_els([_ | _els],
+                                    Cdata) ->
+    decode_sasl_failure_failure_text_els(_els, Cdata);
+decode_sasl_failure_failure_text_els([], Cdata) ->
+    decode_sasl_failure_failure_text_cdata(Cdata).
+
+decode_sasl_failure_failure_text_attrs([{<<"xml:lang">>,
+                                        _val}
+                                       | _attrs],
+                                      _Text_lang) ->
+    decode_sasl_failure_failure_text_attrs(_attrs, _val);
+decode_sasl_failure_failure_text_attrs([_ | _attrs],
+                                      Text_lang) ->
+    decode_sasl_failure_failure_text_attrs(_attrs,
+                                          Text_lang);
+decode_sasl_failure_failure_text_attrs([], Text_lang) ->
+    'decode_sasl_failure_failure_text_xml:lang'(Text_lang).
+
+encode_sasl_failure_failure_text(undefined, _acc) ->
+    _acc;
+encode_sasl_failure_failure_text({Text_lang, Cdata},
+                                _acc) ->
+    _els = encode_sasl_failure_failure_text_cdata(Cdata,
+                                                 []),
+    _attrs =
+       'encode_sasl_failure_failure_text_xml:lang'(Text_lang,
+                                                   []),
+    [{xmlel, <<"text">>, _attrs, _els} | _acc].
+
+'decode_sasl_failure_failure_text_xml:lang'(undefined) ->
+    undefined;
+'decode_sasl_failure_failure_text_xml:lang'(_val) ->
+    _val.
+
+'encode_sasl_failure_failure_text_xml:lang'(undefined,
+                                           _acc) ->
+    _acc;
+'encode_sasl_failure_failure_text_xml:lang'(_val,
+                                           _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_sasl_failure_failure_text_cdata(<<>>) ->
+    undefined;
+decode_sasl_failure_failure_text_cdata(_val) -> _val.
+
+encode_sasl_failure_failure_text_cdata(undefined,
+                                      _acc) ->
+    _acc;
+encode_sasl_failure_failure_text_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_sasl_mechanism_mechanism({xmlel, _, _attrs,
+                                _els}) ->
+    Cdata = decode_sasl_mechanism_mechanism_els(_els, <<>>),
+    Cdata.
+
+decode_sasl_mechanism_mechanism_els([{xmlcdata, _data}
+                                    | _els],
+                                   Cdata) ->
+    decode_sasl_mechanism_mechanism_els(_els,
+                                       <<Cdata/binary, _data/binary>>);
+decode_sasl_mechanism_mechanism_els([_ | _els],
+                                   Cdata) ->
+    decode_sasl_mechanism_mechanism_els(_els, Cdata);
+decode_sasl_mechanism_mechanism_els([], Cdata) ->
+    decode_sasl_mechanism_mechanism_cdata(Cdata).
+
+encode_sasl_mechanism_mechanism([], _acc) -> _acc;
+encode_sasl_mechanism_mechanism([Cdata | _tail],
+                               _acc) ->
+    _els = encode_sasl_mechanism_mechanism_cdata(Cdata, []),
+    _attrs = [],
+    encode_sasl_mechanism_mechanism(_tail,
+                                   [{xmlel, <<"mechanism">>, _attrs, _els}
+                                    | _acc]).
+
+decode_sasl_mechanism_mechanism_cdata(<<>>) ->
+    undefined;
+decode_sasl_mechanism_mechanism_cdata(_val) -> _val.
+
+encode_sasl_mechanism_mechanism_cdata(undefined,
+                                     _acc) ->
+    _acc;
+encode_sasl_mechanism_mechanism_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_sasl_mechanisms_mechanisms({xmlel, _, _attrs,
+                                  _els}) ->
+    Mechanism = decode_sasl_mechanisms_mechanisms_els(_els,
+                                                     []),
+    {sasl_mechanisms, Mechanism}.
+
+decode_sasl_mechanisms_mechanisms_els([{xmlel,
+                                       <<"mechanism">>, _attrs, _} =
+                                          _el
+                                      | _els],
+                                     Mechanism) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_sasl_mechanisms_mechanisms_els(_els,
+                                               [decode_sasl_mechanism_mechanism(_el)
+                                                | Mechanism]);
+      _ ->
+         decode_sasl_mechanisms_mechanisms_els(_els, Mechanism)
+    end;
+decode_sasl_mechanisms_mechanisms_els([_ | _els],
+                                     Mechanism) ->
+    decode_sasl_mechanisms_mechanisms_els(_els, Mechanism);
+decode_sasl_mechanisms_mechanisms_els([], Mechanism) ->
+    xml_gen:reverse(Mechanism, 1, infinity).
+
+encode_sasl_mechanisms_mechanisms(undefined, _acc) ->
+    _acc;
+encode_sasl_mechanisms_mechanisms({sasl_mechanisms,
+                                  Mechanism},
+                                 _acc) ->
+    _els = encode_sasl_mechanism_mechanism(Mechanism, []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-sasl">>}],
+    [{xmlel, <<"mechanisms">>, _attrs, _els} | _acc].
+
+decode_starttls_starttls({xmlel, _, _attrs, _els}) ->
+    Required = decode_starttls_starttls_els(_els, false),
+    {starttls, Required}.
+
+decode_starttls_starttls_els([{xmlel, <<"required">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Required) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_starttls_starttls_els(_els,
+                                      decode_starttls_starttls_required(_el));
+      _ -> decode_starttls_starttls_els(_els, Required)
+    end;
+decode_starttls_starttls_els([_ | _els], Required) ->
+    decode_starttls_starttls_els(_els, Required);
+decode_starttls_starttls_els([], Required) -> Required.
+
+encode_starttls_starttls(undefined, _acc) -> _acc;
+encode_starttls_starttls({starttls, Required}, _acc) ->
+    _els = encode_starttls_starttls_required(Required, []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-tls">>}],
+    [{xmlel, <<"starttls">>, _attrs, _els} | _acc].
+
+decode_starttls_starttls_required({xmlel, _, _attrs,
+                                  _els}) ->
+    true.
+
+encode_starttls_starttls_required(false, _acc) -> _acc;
+encode_starttls_starttls_required(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"required">>, _attrs, _els} | _acc].
+
+decode_starttls_proceed_proceed({xmlel, _, _attrs,
+                                _els}) ->
+    {starttls_proceed}.
+
+encode_starttls_proceed_proceed(undefined, _acc) ->
+    _acc;
+encode_starttls_proceed_proceed({starttls_proceed},
+                               _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-tls">>}],
+    [{xmlel, <<"proceed">>, _attrs, _els} | _acc].
+
+decode_starttls_failure_failure({xmlel, _, _attrs,
+                                _els}) ->
+    {starttls_failure}.
+
+encode_starttls_failure_failure(undefined, _acc) ->
+    _acc;
+encode_starttls_failure_failure({starttls_failure},
+                               _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-tls">>}],
+    [{xmlel, <<"failure">>, _attrs, _els} | _acc].
+
+'decode_stream_features_stream:features'({xmlel, _,
+                                         _attrs, _els}) ->
+    __Els =
+       'decode_stream_features_stream:features_els'(_els, []),
+    {stream_features, __Els}.
+
+'decode_stream_features_stream:features_els'([{xmlel, _,
+                                              _, _} =
+                                                 _el
+                                             | _els],
+                                            __Els) ->
+    'decode_stream_features_stream:features_els'(_els,
+                                                [decode(_el) | __Els]);
+'decode_stream_features_stream:features_els'([_ | _els],
+                                            __Els) ->
+    'decode_stream_features_stream:features_els'(_els,
+                                                __Els);
+'decode_stream_features_stream:features_els'([],
+                                            __Els) ->
+    lists:reverse(__Els).
+
+'encode_stream_features_stream:features'(undefined,
+                                        _acc) ->
+    _acc;
+'encode_stream_features_stream:features'({stream_features,
+                                         __Els},
+                                        _acc) ->
+    _els = [encode(_subel) || _subel <- __Els] ++ [],
+    _attrs = [],
+    [{xmlel, <<"stream:features">>, _attrs, _els} | _acc].
+
+decode_p1_push_push({xmlel, _, _attrs, _els}) ->
+    {p1_push}.
+
+encode_p1_push_push(undefined, _acc) -> _acc;
+encode_p1_push_push({p1_push}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>, <<"p1:push">>}],
+    [{xmlel, <<"push">>, _attrs, _els} | _acc].
+
+decode_p1_rebind_rebind({xmlel, _, _attrs, _els}) ->
+    {p1_rebind}.
+
+encode_p1_rebind_rebind(undefined, _acc) -> _acc;
+encode_p1_rebind_rebind({p1_rebind}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>, <<"p1:rebind">>}],
+    [{xmlel, <<"rebind">>, _attrs, _els} | _acc].
+
+decode_p1_ack_ack({xmlel, _, _attrs, _els}) -> {p1_ack}.
+
+encode_p1_ack_ack(undefined, _acc) -> _acc;
+encode_p1_ack_ack({p1_ack}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>, <<"p1:ack">>}],
+    [{xmlel, <<"ack">>, _attrs, _els} | _acc].
+
+decode_caps_c({xmlel, _, _attrs, _els}) ->
+    {Ver, Node, Hash} = decode_caps_c_attrs(_attrs,
+                                           undefined, undefined, undefined),
+    {caps, Hash, Node, Ver}.
+
+decode_caps_c_attrs([{<<"ver">>, _val} | _attrs], _Ver,
+                   Node, Hash) ->
+    decode_caps_c_attrs(_attrs, _val, Node, Hash);
+decode_caps_c_attrs([{<<"node">>, _val} | _attrs], Ver,
+                   _Node, Hash) ->
+    decode_caps_c_attrs(_attrs, Ver, _val, Hash);
+decode_caps_c_attrs([{<<"hash">>, _val} | _attrs], Ver,
+                   Node, _Hash) ->
+    decode_caps_c_attrs(_attrs, Ver, Node, _val);
+decode_caps_c_attrs([_ | _attrs], Ver, Node, Hash) ->
+    decode_caps_c_attrs(_attrs, Ver, Node, Hash);
+decode_caps_c_attrs([], Ver, Node, Hash) ->
+    {decode_caps_c_ver(Ver), decode_caps_c_node(Node),
+     decode_caps_c_hash(Hash)}.
+
+encode_caps_c(undefined, _acc) -> _acc;
+encode_caps_c({caps, Hash, Node, Ver}, _acc) ->
+    _els = [],
+    _attrs = encode_caps_c_hash(Hash,
+                               encode_caps_c_node(Node,
+                                                  encode_caps_c_ver(Ver,
+                                                                    [{<<"xmlns">>,
+                                                                      <<"http://jabber.org/protocol/caps">>}]))),
+    [{xmlel, <<"c">>, _attrs, _els} | _acc].
+
+decode_caps_c_hash(undefined) -> undefined;
+decode_caps_c_hash(_val) -> _val.
+
+encode_caps_c_hash(undefined, _acc) -> _acc;
+encode_caps_c_hash(_val, _acc) ->
+    [{<<"hash">>, _val} | _acc].
+
+decode_caps_c_node(undefined) -> undefined;
+decode_caps_c_node(_val) -> _val.
+
+encode_caps_c_node(undefined, _acc) -> _acc;
+encode_caps_c_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_caps_c_ver(undefined) -> undefined;
+decode_caps_c_ver(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"ver">>, <<"c">>,
+                       <<"http://jabber.org/protocol/caps">>});
+      _res -> _res
+    end.
+
+encode_caps_c_ver(undefined, _acc) -> _acc;
+encode_caps_c_ver(_val, _acc) ->
+    [{<<"ver">>, base64:encode(_val)} | _acc].
+
+decode_register_register({xmlel, _, _attrs, _els}) ->
+    {register}.
+
+encode_register_register(undefined, _acc) -> _acc;
+encode_register_register({register}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"http://jabber.org/features/iq-register">>}],
+    [{xmlel, <<"register">>, _attrs, _els} | _acc].
+
+decode_session_session({xmlel, _, _attrs, _els}) ->
+    {session}.
+
+encode_session_session(undefined, _acc) -> _acc;
+encode_session_session({session}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-session">>}],
+    [{xmlel, <<"session">>, _attrs, _els} | _acc].
+
+decode_ping_ping({xmlel, _, _attrs, _els}) -> {ping}.
+
+encode_ping_ping(undefined, _acc) -> _acc;
+encode_ping_ping({ping}, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>, <<"urn:xmpp:ping">>}],
+    [{xmlel, <<"ping">>, _attrs, _els} | _acc].
+
+decode_time_time({xmlel, _, _attrs, _els}) ->
+    {Utc, Tzo} = decode_time_time_els(_els, undefined,
+                                     undefined),
+    {time, Tzo, Utc}.
+
+decode_time_time_els([{xmlel, <<"utc">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Utc, Tzo) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_time_time_els(_els, decode_time_time_utc(_el),
+                              Tzo);
+      _ -> decode_time_time_els(_els, Utc, Tzo)
+    end;
+decode_time_time_els([{xmlel, <<"tzo">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Utc, Tzo) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_time_time_els(_els, Utc,
+                              decode_time_time_tzo(_el));
+      _ -> decode_time_time_els(_els, Utc, Tzo)
+    end;
+decode_time_time_els([_ | _els], Utc, Tzo) ->
+    decode_time_time_els(_els, Utc, Tzo);
+decode_time_time_els([], Utc, Tzo) -> {Utc, Tzo}.
+
+encode_time_time(undefined, _acc) -> _acc;
+encode_time_time({time, Tzo, Utc}, _acc) ->
+    _els = encode_time_time_tzo(Tzo,
+                               encode_time_time_utc(Utc, [])),
+    _attrs = [{<<"xmlns">>, <<"urn:xmpp:time">>}],
+    [{xmlel, <<"time">>, _attrs, _els} | _acc].
+
+decode_time_time_utc({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_time_time_utc_els(_els, <<>>), Cdata.
+
+decode_time_time_utc_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_time_time_utc_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_time_time_utc_els([_ | _els], Cdata) ->
+    decode_time_time_utc_els(_els, Cdata);
+decode_time_time_utc_els([], Cdata) ->
+    decode_time_time_utc_cdata(Cdata).
+
+encode_time_time_utc(undefined, _acc) -> _acc;
+encode_time_time_utc(Cdata, _acc) ->
+    _els = encode_time_time_utc_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"utc">>, _attrs, _els} | _acc].
+
+decode_time_time_utc_cdata(<<>>) -> undefined;
+decode_time_time_utc_cdata(_val) ->
+    case catch dec_utc(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"utc">>, <<>>});
+      _res -> _res
+    end.
+
+encode_time_time_utc_cdata(undefined, _acc) -> _acc;
+encode_time_time_utc_cdata(_val, _acc) ->
+    [{xmlcdata, enc_utc(_val)} | _acc].
+
+decode_time_time_tzo({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_time_time_tzo_els(_els, <<>>), Cdata.
+
+decode_time_time_tzo_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_time_time_tzo_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_time_time_tzo_els([_ | _els], Cdata) ->
+    decode_time_time_tzo_els(_els, Cdata);
+decode_time_time_tzo_els([], Cdata) ->
+    decode_time_time_tzo_cdata(Cdata).
+
+encode_time_time_tzo(undefined, _acc) -> _acc;
+encode_time_time_tzo(Cdata, _acc) ->
+    _els = encode_time_time_tzo_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"tzo">>, _attrs, _els} | _acc].
+
+decode_time_time_tzo_cdata(<<>>) -> undefined;
+decode_time_time_tzo_cdata(_val) ->
+    case catch dec_tzo(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"tzo">>, <<>>});
+      _res -> _res
+    end.
+
+encode_time_time_tzo_cdata(undefined, _acc) -> _acc;
+encode_time_time_tzo_cdata(_val, _acc) ->
+    [{xmlcdata, enc_tzo(_val)} | _acc].
+
+'decode_stream_error_stream:error'({xmlel, _, _attrs,
+                                   _els}) ->
+    {Text, Reason} =
+       'decode_stream_error_stream:error_els'(_els, undefined,
+                                              undefined),
+    {stream_error, Reason, Text}.
+
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"text">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els,
+                                                'decode_stream_error_stream:error_text'(_el),
+                                                Reason);
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"unsupported-version">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_unsupported-version'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"unsupported-stanza-type">>, _attrs,
+                                        _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_unsupported-stanza-type'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"unsupported-encoding">>, _attrs,
+                                        _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_unsupported-encoding'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"undefined-condition">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_undefined-condition'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"system-shutdown">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_system-shutdown'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"see-other-host">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_see-other-host'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"restricted-xml">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_restricted-xml'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"resource-constraint">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_resource-constraint'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"reset">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_reset'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"remote-connection-failed">>, _attrs,
+                                        _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_remote-connection-failed'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"policy-violation">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_policy-violation'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"not-well-formed">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_not-well-formed'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"not-authorized">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_not-authorized'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"invalid-xml">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_invalid-xml'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"invalid-namespace">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_invalid-namespace'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"invalid-id">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_invalid-id'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"invalid-from">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_invalid-from'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"internal-server-error">>, _attrs,
+                                        _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_internal-server-error'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"improper-addressing">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_improper-addressing'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"host-unknown">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_host-unknown'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"host-gone">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_host-gone'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"connection-timeout">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_connection-timeout'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"conflict">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_conflict'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"bad-namespace-prefix">>, _attrs,
+                                        _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_bad-namespace-prefix'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([{xmlel,
+                                        <<"bad-format">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Text, Reason) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                'decode_stream_error_stream:error_bad-format'(_el));
+      _ ->
+         'decode_stream_error_stream:error_els'(_els, Text,
+                                                Reason)
+    end;
+'decode_stream_error_stream:error_els'([_ | _els], Text,
+                                      Reason) ->
+    'decode_stream_error_stream:error_els'(_els, Text,
+                                          Reason);
+'decode_stream_error_stream:error_els'([], Text,
+                                      Reason) ->
+    {Text, Reason}.
+
+'encode_stream_error_stream:error_$reason'(undefined,
+                                          _acc) ->
+    _acc;
+'encode_stream_error_stream:error_$reason'('unsupported-version' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_unsupported-version'(_r,
+                                                          _acc);
+'encode_stream_error_stream:error_$reason'('unsupported-stanza-type' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_unsupported-stanza-type'(_r,
+                                                              _acc);
+'encode_stream_error_stream:error_$reason'('unsupported-encoding' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_unsupported-encoding'(_r,
+                                                           _acc);
+'encode_stream_error_stream:error_$reason'('undefined-condition' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_undefined-condition'(_r,
+                                                          _acc);
+'encode_stream_error_stream:error_$reason'('system-shutdown' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_system-shutdown'(_r,
+                                                      _acc);
+'encode_stream_error_stream:error_$reason'({'see-other-host',
+                                           _} =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_see-other-host'(_r,
+                                                     _acc);
+'encode_stream_error_stream:error_$reason'('restricted-xml' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_restricted-xml'(_r,
+                                                     _acc);
+'encode_stream_error_stream:error_$reason'('resource-constraint' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_resource-constraint'(_r,
+                                                          _acc);
+'encode_stream_error_stream:error_$reason'(reset = _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_reset'(_r, _acc);
+'encode_stream_error_stream:error_$reason'('remote-connection-failed' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_remote-connection-failed'(_r,
+                                                               _acc);
+'encode_stream_error_stream:error_$reason'('policy-violation' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_policy-violation'(_r,
+                                                       _acc);
+'encode_stream_error_stream:error_$reason'('not-well-formed' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_not-well-formed'(_r,
+                                                      _acc);
+'encode_stream_error_stream:error_$reason'('not-authorized' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_not-authorized'(_r,
+                                                     _acc);
+'encode_stream_error_stream:error_$reason'('invalid-xml' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_invalid-xml'(_r,
+                                                  _acc);
+'encode_stream_error_stream:error_$reason'('invalid-namespace' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_invalid-namespace'(_r,
+                                                        _acc);
+'encode_stream_error_stream:error_$reason'('invalid-id' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_invalid-id'(_r, _acc);
+'encode_stream_error_stream:error_$reason'('invalid-from' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_invalid-from'(_r,
+                                                   _acc);
+'encode_stream_error_stream:error_$reason'('internal-server-error' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_internal-server-error'(_r,
+                                                            _acc);
+'encode_stream_error_stream:error_$reason'('improper-addressing' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_improper-addressing'(_r,
+                                                          _acc);
+'encode_stream_error_stream:error_$reason'('host-unknown' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_host-unknown'(_r,
+                                                   _acc);
+'encode_stream_error_stream:error_$reason'('host-gone' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_host-gone'(_r, _acc);
+'encode_stream_error_stream:error_$reason'('connection-timeout' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_connection-timeout'(_r,
+                                                         _acc);
+'encode_stream_error_stream:error_$reason'(conflict =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_conflict'(_r, _acc);
+'encode_stream_error_stream:error_$reason'('bad-namespace-prefix' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_bad-namespace-prefix'(_r,
+                                                           _acc);
+'encode_stream_error_stream:error_$reason'('bad-format' =
+                                              _r,
+                                          _acc) ->
+    'encode_stream_error_stream:error_bad-format'(_r, _acc).
+
+'encode_stream_error_stream:error'(undefined, _acc) ->
+    _acc;
+'encode_stream_error_stream:error'({stream_error,
+                                   Reason, Text},
+                                  _acc) ->
+    _els =
+       'encode_stream_error_stream:error_$reason'(Reason,
+                                                  'encode_stream_error_stream:error_text'(Text,
+                                                                                          [])),
+    _attrs = [],
+    [{xmlel, <<"stream:error">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_unsupported-version'({xmlel,
+                                                       _, _attrs, _els}) ->
+    'unsupported-version'.
+
+'encode_stream_error_stream:error_unsupported-version'(undefined,
+                                                      _acc) ->
+    _acc;
+'encode_stream_error_stream:error_unsupported-version'('unsupported-version',
+                                                      _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"unsupported-version">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_unsupported-stanza-type'({xmlel,
+                                                           _, _attrs, _els}) ->
+    'unsupported-stanza-type'.
+
+'encode_stream_error_stream:error_unsupported-stanza-type'(undefined,
+                                                          _acc) ->
+    _acc;
+'encode_stream_error_stream:error_unsupported-stanza-type'('unsupported-stanza-type',
+                                                          _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"unsupported-stanza-type">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_unsupported-encoding'({xmlel,
+                                                        _, _attrs, _els}) ->
+    'unsupported-encoding'.
+
+'encode_stream_error_stream:error_unsupported-encoding'(undefined,
+                                                       _acc) ->
+    _acc;
+'encode_stream_error_stream:error_unsupported-encoding'('unsupported-encoding',
+                                                       _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"unsupported-encoding">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_undefined-condition'({xmlel,
+                                                       _, _attrs, _els}) ->
+    'undefined-condition'.
+
+'encode_stream_error_stream:error_undefined-condition'(undefined,
+                                                      _acc) ->
+    _acc;
+'encode_stream_error_stream:error_undefined-condition'('undefined-condition',
+                                                      _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"undefined-condition">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_system-shutdown'({xmlel,
+                                                   _, _attrs, _els}) ->
+    'system-shutdown'.
+
+'encode_stream_error_stream:error_system-shutdown'(undefined,
+                                                  _acc) ->
+    _acc;
+'encode_stream_error_stream:error_system-shutdown'('system-shutdown',
+                                                  _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"system-shutdown">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_see-other-host'({xmlel,
+                                                  _, _attrs, _els}) ->
+    Cdata =
+       'decode_stream_error_stream:error_see-other-host_els'(_els,
+                                                             <<>>),
+    {'see-other-host', Cdata}.
+
+'decode_stream_error_stream:error_see-other-host_els'([{xmlcdata,
+                                                       _data}
+                                                      | _els],
+                                                     Cdata) ->
+    'decode_stream_error_stream:error_see-other-host_els'(_els,
+                                                         <<Cdata/binary,
+                                                           _data/binary>>);
+'decode_stream_error_stream:error_see-other-host_els'([_
+                                                      | _els],
+                                                     Cdata) ->
+    'decode_stream_error_stream:error_see-other-host_els'(_els,
+                                                         Cdata);
+'decode_stream_error_stream:error_see-other-host_els'([],
+                                                     Cdata) ->
+    'decode_stream_error_stream:error_see-other-host_cdata'(Cdata).
+
+'encode_stream_error_stream:error_see-other-host'(undefined,
+                                                 _acc) ->
+    _acc;
+'encode_stream_error_stream:error_see-other-host'({'see-other-host',
+                                                  Cdata},
+                                                 _acc) ->
+    _els =
+       'encode_stream_error_stream:error_see-other-host_cdata'(Cdata,
+                                                               []),
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"see-other-host">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_see-other-host_cdata'(<<>>) ->
+    undefined;
+'decode_stream_error_stream:error_see-other-host_cdata'(_val) ->
+    _val.
+
+'encode_stream_error_stream:error_see-other-host_cdata'(undefined,
+                                                       _acc) ->
+    _acc;
+'encode_stream_error_stream:error_see-other-host_cdata'(_val,
+                                                       _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+'decode_stream_error_stream:error_restricted-xml'({xmlel,
+                                                  _, _attrs, _els}) ->
+    'restricted-xml'.
+
+'encode_stream_error_stream:error_restricted-xml'(undefined,
+                                                 _acc) ->
+    _acc;
+'encode_stream_error_stream:error_restricted-xml'('restricted-xml',
+                                                 _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"restricted-xml">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_resource-constraint'({xmlel,
+                                                       _, _attrs, _els}) ->
+    'resource-constraint'.
+
+'encode_stream_error_stream:error_resource-constraint'(undefined,
+                                                      _acc) ->
+    _acc;
+'encode_stream_error_stream:error_resource-constraint'('resource-constraint',
+                                                      _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"resource-constraint">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_reset'({xmlel, _,
+                                         _attrs, _els}) ->
+    reset.
+
+'encode_stream_error_stream:error_reset'(undefined,
+                                        _acc) ->
+    _acc;
+'encode_stream_error_stream:error_reset'(reset, _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"reset">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_remote-connection-failed'({xmlel,
+                                                            _, _attrs,
+                                                            _els}) ->
+    'remote-connection-failed'.
+
+'encode_stream_error_stream:error_remote-connection-failed'(undefined,
+                                                           _acc) ->
+    _acc;
+'encode_stream_error_stream:error_remote-connection-failed'('remote-connection-failed',
+                                                           _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"remote-connection-failed">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_policy-violation'({xmlel,
+                                                    _, _attrs, _els}) ->
+    'policy-violation'.
+
+'encode_stream_error_stream:error_policy-violation'(undefined,
+                                                   _acc) ->
+    _acc;
+'encode_stream_error_stream:error_policy-violation'('policy-violation',
+                                                   _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"policy-violation">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_not-well-formed'({xmlel,
+                                                   _, _attrs, _els}) ->
+    'not-well-formed'.
+
+'encode_stream_error_stream:error_not-well-formed'(undefined,
+                                                  _acc) ->
+    _acc;
+'encode_stream_error_stream:error_not-well-formed'('not-well-formed',
+                                                  _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"not-well-formed">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_not-authorized'({xmlel,
+                                                  _, _attrs, _els}) ->
+    'not-authorized'.
+
+'encode_stream_error_stream:error_not-authorized'(undefined,
+                                                 _acc) ->
+    _acc;
+'encode_stream_error_stream:error_not-authorized'('not-authorized',
+                                                 _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"not-authorized">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_invalid-xml'({xmlel,
+                                               _, _attrs, _els}) ->
+    'invalid-xml'.
+
+'encode_stream_error_stream:error_invalid-xml'(undefined,
+                                              _acc) ->
+    _acc;
+'encode_stream_error_stream:error_invalid-xml'('invalid-xml',
+                                              _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"invalid-xml">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_invalid-namespace'({xmlel,
+                                                     _, _attrs, _els}) ->
+    'invalid-namespace'.
+
+'encode_stream_error_stream:error_invalid-namespace'(undefined,
+                                                    _acc) ->
+    _acc;
+'encode_stream_error_stream:error_invalid-namespace'('invalid-namespace',
+                                                    _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"invalid-namespace">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_invalid-id'({xmlel, _,
+                                              _attrs, _els}) ->
+    'invalid-id'.
+
+'encode_stream_error_stream:error_invalid-id'(undefined,
+                                             _acc) ->
+    _acc;
+'encode_stream_error_stream:error_invalid-id'('invalid-id',
+                                             _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"invalid-id">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_invalid-from'({xmlel,
+                                                _, _attrs, _els}) ->
+    'invalid-from'.
+
+'encode_stream_error_stream:error_invalid-from'(undefined,
+                                               _acc) ->
+    _acc;
+'encode_stream_error_stream:error_invalid-from'('invalid-from',
+                                               _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"invalid-from">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_internal-server-error'({xmlel,
+                                                         _, _attrs, _els}) ->
+    'internal-server-error'.
+
+'encode_stream_error_stream:error_internal-server-error'(undefined,
+                                                        _acc) ->
+    _acc;
+'encode_stream_error_stream:error_internal-server-error'('internal-server-error',
+                                                        _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"internal-server-error">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_improper-addressing'({xmlel,
+                                                       _, _attrs, _els}) ->
+    'improper-addressing'.
+
+'encode_stream_error_stream:error_improper-addressing'(undefined,
+                                                      _acc) ->
+    _acc;
+'encode_stream_error_stream:error_improper-addressing'('improper-addressing',
+                                                      _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"improper-addressing">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_host-unknown'({xmlel,
+                                                _, _attrs, _els}) ->
+    'host-unknown'.
+
+'encode_stream_error_stream:error_host-unknown'(undefined,
+                                               _acc) ->
+    _acc;
+'encode_stream_error_stream:error_host-unknown'('host-unknown',
+                                               _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"host-unknown">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_host-gone'({xmlel, _,
+                                             _attrs, _els}) ->
+    'host-gone'.
+
+'encode_stream_error_stream:error_host-gone'(undefined,
+                                            _acc) ->
+    _acc;
+'encode_stream_error_stream:error_host-gone'('host-gone',
+                                            _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"host-gone">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_connection-timeout'({xmlel,
+                                                      _, _attrs, _els}) ->
+    'connection-timeout'.
+
+'encode_stream_error_stream:error_connection-timeout'(undefined,
+                                                     _acc) ->
+    _acc;
+'encode_stream_error_stream:error_connection-timeout'('connection-timeout',
+                                                     _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"connection-timeout">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_conflict'({xmlel, _,
+                                            _attrs, _els}) ->
+    conflict.
+
+'encode_stream_error_stream:error_conflict'(undefined,
+                                           _acc) ->
+    _acc;
+'encode_stream_error_stream:error_conflict'(conflict,
+                                           _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"conflict">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_bad-namespace-prefix'({xmlel,
+                                                        _, _attrs, _els}) ->
+    'bad-namespace-prefix'.
+
+'encode_stream_error_stream:error_bad-namespace-prefix'(undefined,
+                                                       _acc) ->
+    _acc;
+'encode_stream_error_stream:error_bad-namespace-prefix'('bad-namespace-prefix',
+                                                       _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"bad-namespace-prefix">>, _attrs, _els}
+     | _acc].
+
+'decode_stream_error_stream:error_bad-format'({xmlel, _,
+                                              _attrs, _els}) ->
+    'bad-format'.
+
+'encode_stream_error_stream:error_bad-format'(undefined,
+                                             _acc) ->
+    _acc;
+'encode_stream_error_stream:error_bad-format'('bad-format',
+                                             _acc) ->
+    _els = [],
+    _attrs = [{<<"xmlns">>,
+              <<"urn:ietf:params:xml:ns:xmpp-streams">>}],
+    [{xmlel, <<"bad-format">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_text'({xmlel, _,
+                                        _attrs, _els}) ->
+    Text_lang =
+       'decode_stream_error_stream:error_text_attrs'(_attrs,
+                                                     undefined),
+    Cdata =
+       'decode_stream_error_stream:error_text_els'(_els, <<>>),
+    {Text_lang, Cdata}.
+
+'decode_stream_error_stream:error_text_els'([{xmlcdata,
+                                             _data}
+                                            | _els],
+                                           Cdata) ->
+    'decode_stream_error_stream:error_text_els'(_els,
+                                               <<Cdata/binary, _data/binary>>);
+'decode_stream_error_stream:error_text_els'([_ | _els],
+                                           Cdata) ->
+    'decode_stream_error_stream:error_text_els'(_els,
+                                               Cdata);
+'decode_stream_error_stream:error_text_els'([],
+                                           Cdata) ->
+    'decode_stream_error_stream:error_text_cdata'(Cdata).
+
+'decode_stream_error_stream:error_text_attrs'([{<<"xml:lang">>,
+                                               _val}
+                                              | _attrs],
+                                             _Text_lang) ->
+    'decode_stream_error_stream:error_text_attrs'(_attrs,
+                                                 _val);
+'decode_stream_error_stream:error_text_attrs'([_
+                                              | _attrs],
+                                             Text_lang) ->
+    'decode_stream_error_stream:error_text_attrs'(_attrs,
+                                                 Text_lang);
+'decode_stream_error_stream:error_text_attrs'([],
+                                             Text_lang) ->
+    'decode_stream_error_stream:error_text_xml:lang'(Text_lang).
+
+'encode_stream_error_stream:error_text'(undefined,
+                                       _acc) ->
+    _acc;
+'encode_stream_error_stream:error_text'({Text_lang,
+                                        Cdata},
+                                       _acc) ->
+    _els =
+       'encode_stream_error_stream:error_text_cdata'(Cdata,
+                                                     []),
+    _attrs =
+       'encode_stream_error_stream:error_text_xml:lang'(Text_lang,
+                                                        [{<<"xmlns">>,
+                                                          <<"urn:ietf:params:xml:ns:xmpp-streams">>}]),
+    [{xmlel, <<"text">>, _attrs, _els} | _acc].
+
+'decode_stream_error_stream:error_text_xml:lang'(undefined) ->
+    undefined;
+'decode_stream_error_stream:error_text_xml:lang'(_val) ->
+    _val.
+
+'encode_stream_error_stream:error_text_xml:lang'(undefined,
+                                                _acc) ->
+    _acc;
+'encode_stream_error_stream:error_text_xml:lang'(_val,
+                                                _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+'decode_stream_error_stream:error_text_cdata'(<<>>) ->
+    undefined;
+'decode_stream_error_stream:error_text_cdata'(_val) ->
+    _val.
+
+'encode_stream_error_stream:error_text_cdata'(undefined,
+                                             _acc) ->
+    _acc;
+'encode_stream_error_stream:error_text_cdata'(_val,
+                                             _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_name_N({xmlel, _, _attrs, _els}) ->
+    {Suffix, Prefix, Middle, Given, Family} =
+       decode_vcard_name_N_els(_els, undefined, undefined,
+                               undefined, undefined, undefined),
+    {vcard_name, Family, Given, Middle, Prefix, Suffix}.
+
+decode_vcard_name_N_els([{xmlel, <<"SUFFIX">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Suffix, Prefix, Middle, Given, Family) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_name_N_els(_els,
+                                 decode_vcard_name_N_SUFFIX(_el), Prefix,
+                                 Middle, Given, Family);
+      _ ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                                 Given, Family)
+    end;
+decode_vcard_name_N_els([{xmlel, <<"PREFIX">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Suffix, Prefix, Middle, Given, Family) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_name_N_els(_els, Suffix,
+                                 decode_vcard_name_N_PREFIX(_el), Middle,
+                                 Given, Family);
+      _ ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                                 Given, Family)
+    end;
+decode_vcard_name_N_els([{xmlel, <<"MIDDLE">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Suffix, Prefix, Middle, Given, Family) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix,
+                                 decode_vcard_name_N_MIDDLE(_el), Given,
+                                 Family);
+      _ ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                                 Given, Family)
+    end;
+decode_vcard_name_N_els([{xmlel, <<"GIVEN">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Suffix, Prefix, Middle, Given, Family) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                                 decode_vcard_name_N_GIVEN(_el), Family);
+      _ ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                                 Given, Family)
+    end;
+decode_vcard_name_N_els([{xmlel, <<"FAMILY">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Suffix, Prefix, Middle, Given, Family) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                                 Given, decode_vcard_name_N_FAMILY(_el));
+      _ ->
+         decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                                 Given, Family)
+    end;
+decode_vcard_name_N_els([_ | _els], Suffix, Prefix,
+                       Middle, Given, Family) ->
+    decode_vcard_name_N_els(_els, Suffix, Prefix, Middle,
+                           Given, Family);
+decode_vcard_name_N_els([], Suffix, Prefix, Middle,
+                       Given, Family) ->
+    {Suffix, Prefix, Middle, Given, Family}.
+
+encode_vcard_name_N(undefined, _acc) -> _acc;
+encode_vcard_name_N({vcard_name, Family, Given, Middle,
+                    Prefix, Suffix},
+                   _acc) ->
+    _els = encode_vcard_name_N_FAMILY(Family,
+                                     encode_vcard_name_N_GIVEN(Given,
+                                                               encode_vcard_name_N_MIDDLE(Middle,
+                                                                                          encode_vcard_name_N_PREFIX(Prefix,
+                                                                                                                     encode_vcard_name_N_SUFFIX(Suffix,
+                                                                                                                                                []))))),
+    _attrs = [],
+    [{xmlel, <<"N">>, _attrs, _els} | _acc].
+
+decode_vcard_name_N_SUFFIX({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_name_N_SUFFIX_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_name_N_SUFFIX_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_name_N_SUFFIX_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_name_N_SUFFIX_els([_ | _els], Cdata) ->
+    decode_vcard_name_N_SUFFIX_els(_els, Cdata);
+decode_vcard_name_N_SUFFIX_els([], Cdata) ->
+    decode_vcard_name_N_SUFFIX_cdata(Cdata).
+
+encode_vcard_name_N_SUFFIX(undefined, _acc) -> _acc;
+encode_vcard_name_N_SUFFIX(Cdata, _acc) ->
+    _els = encode_vcard_name_N_SUFFIX_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"SUFFIX">>, _attrs, _els} | _acc].
+
+decode_vcard_name_N_SUFFIX_cdata(<<>>) -> undefined;
+decode_vcard_name_N_SUFFIX_cdata(_val) -> _val.
+
+encode_vcard_name_N_SUFFIX_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_name_N_SUFFIX_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_name_N_PREFIX({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_name_N_PREFIX_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_name_N_PREFIX_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_name_N_PREFIX_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_name_N_PREFIX_els([_ | _els], Cdata) ->
+    decode_vcard_name_N_PREFIX_els(_els, Cdata);
+decode_vcard_name_N_PREFIX_els([], Cdata) ->
+    decode_vcard_name_N_PREFIX_cdata(Cdata).
+
+encode_vcard_name_N_PREFIX(undefined, _acc) -> _acc;
+encode_vcard_name_N_PREFIX(Cdata, _acc) ->
+    _els = encode_vcard_name_N_PREFIX_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"PREFIX">>, _attrs, _els} | _acc].
+
+decode_vcard_name_N_PREFIX_cdata(<<>>) -> undefined;
+decode_vcard_name_N_PREFIX_cdata(_val) -> _val.
+
+encode_vcard_name_N_PREFIX_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_name_N_PREFIX_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_name_N_MIDDLE({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_name_N_MIDDLE_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_name_N_MIDDLE_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_name_N_MIDDLE_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_name_N_MIDDLE_els([_ | _els], Cdata) ->
+    decode_vcard_name_N_MIDDLE_els(_els, Cdata);
+decode_vcard_name_N_MIDDLE_els([], Cdata) ->
+    decode_vcard_name_N_MIDDLE_cdata(Cdata).
+
+encode_vcard_name_N_MIDDLE(undefined, _acc) -> _acc;
+encode_vcard_name_N_MIDDLE(Cdata, _acc) ->
+    _els = encode_vcard_name_N_MIDDLE_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"MIDDLE">>, _attrs, _els} | _acc].
+
+decode_vcard_name_N_MIDDLE_cdata(<<>>) -> undefined;
+decode_vcard_name_N_MIDDLE_cdata(_val) -> _val.
+
+encode_vcard_name_N_MIDDLE_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_name_N_MIDDLE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_name_N_GIVEN({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_name_N_GIVEN_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_name_N_GIVEN_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_vcard_name_N_GIVEN_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_vcard_name_N_GIVEN_els([_ | _els], Cdata) ->
+    decode_vcard_name_N_GIVEN_els(_els, Cdata);
+decode_vcard_name_N_GIVEN_els([], Cdata) ->
+    decode_vcard_name_N_GIVEN_cdata(Cdata).
+
+encode_vcard_name_N_GIVEN(undefined, _acc) -> _acc;
+encode_vcard_name_N_GIVEN(Cdata, _acc) ->
+    _els = encode_vcard_name_N_GIVEN_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"GIVEN">>, _attrs, _els} | _acc].
+
+decode_vcard_name_N_GIVEN_cdata(<<>>) -> undefined;
+decode_vcard_name_N_GIVEN_cdata(_val) -> _val.
+
+encode_vcard_name_N_GIVEN_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_name_N_GIVEN_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_name_N_FAMILY({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_name_N_FAMILY_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_name_N_FAMILY_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_name_N_FAMILY_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_name_N_FAMILY_els([_ | _els], Cdata) ->
+    decode_vcard_name_N_FAMILY_els(_els, Cdata);
+decode_vcard_name_N_FAMILY_els([], Cdata) ->
+    decode_vcard_name_N_FAMILY_cdata(Cdata).
+
+encode_vcard_name_N_FAMILY(undefined, _acc) -> _acc;
+encode_vcard_name_N_FAMILY(Cdata, _acc) ->
+    _els = encode_vcard_name_N_FAMILY_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"FAMILY">>, _attrs, _els} | _acc].
+
+decode_vcard_name_N_FAMILY_cdata(<<>>) -> undefined;
+decode_vcard_name_N_FAMILY_cdata(_val) -> _val.
+
+encode_vcard_name_N_FAMILY_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_name_N_FAMILY_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR({xmlel, _, _attrs, _els}) ->
+    {Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+     Pref, Intl, Dom, Parcel, Postal, Work, Home} =
+       decode_vcard_adr_ADR_els(_els, undefined, undefined,
+                                undefined, undefined, undefined, undefined,
+                                undefined, false, false, false, false, false,
+                                false, false),
+    {vcard_adr, Home, Work, Postal, Parcel, Dom, Intl, Pref,
+     Pobox, Extadd, Street, Locality, Region, Pcode, Ctry}.
+
+decode_vcard_adr_ADR_els([{xmlel, <<"CTRY">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els,
+                                  decode_vcard_adr_ADR_CTRY(_el), Pcode,
+                                  Region, Locality, Street, Extadd, Pobox,
+                                  Pref, Intl, Dom, Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"PCODE">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry,
+                                  decode_vcard_adr_ADR_PCODE(_el), Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"REGION">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode,
+                                  decode_vcard_adr_ADR_REGION(_el), Locality,
+                                  Street, Extadd, Pobox, Pref, Intl, Dom,
+                                  Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"LOCALITY">>,
+                          _attrs, _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  decode_vcard_adr_ADR_LOCALITY(_el), Street,
+                                  Extadd, Pobox, Pref, Intl, Dom, Parcel,
+                                  Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"STREET">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, decode_vcard_adr_ADR_STREET(_el),
+                                  Extadd, Pobox, Pref, Intl, Dom, Parcel,
+                                  Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"EXTADD">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street,
+                                  decode_vcard_adr_ADR_EXTADD(_el), Pobox,
+                                  Pref, Intl, Dom, Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"POBOX">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd,
+                                  decode_vcard_adr_ADR_POBOX(_el), Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"PREF">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox,
+                                  decode_vcard_adr_ADR_PREF(_el), Intl, Dom,
+                                  Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"INTL">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref,
+                                  decode_vcard_adr_ADR_INTL(_el), Dom, Parcel,
+                                  Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"DOM">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  decode_vcard_adr_ADR_DOM(_el), Parcel,
+                                  Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"PARCEL">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, decode_vcard_adr_ADR_PARCEL(_el),
+                                  Postal, Work, Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"POSTAL">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel,
+                                  decode_vcard_adr_ADR_POSTAL(_el), Work,
+                                  Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"WORK">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal,
+                                  decode_vcard_adr_ADR_WORK(_el), Home);
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([{xmlel, <<"HOME">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+                        Pref, Intl, Dom, Parcel, Postal, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work,
+                                  decode_vcard_adr_ADR_HOME(_el));
+      _ ->
+         decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                                  Locality, Street, Extadd, Pobox, Pref, Intl,
+                                  Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_adr_ADR_els([_ | _els], Ctry, Pcode,
+                        Region, Locality, Street, Extadd, Pobox, Pref, Intl,
+                        Dom, Parcel, Postal, Work, Home) ->
+    decode_vcard_adr_ADR_els(_els, Ctry, Pcode, Region,
+                            Locality, Street, Extadd, Pobox, Pref, Intl, Dom,
+                            Parcel, Postal, Work, Home);
+decode_vcard_adr_ADR_els([], Ctry, Pcode, Region,
+                        Locality, Street, Extadd, Pobox, Pref, Intl, Dom,
+                        Parcel, Postal, Work, Home) ->
+    {Ctry, Pcode, Region, Locality, Street, Extadd, Pobox,
+     Pref, Intl, Dom, Parcel, Postal, Work, Home}.
+
+encode_vcard_adr_ADR([], _acc) -> _acc;
+encode_vcard_adr_ADR([{vcard_adr, Home, Work, Postal,
+                      Parcel, Dom, Intl, Pref, Pobox, Extadd, Street,
+                      Locality, Region, Pcode, Ctry}
+                     | _tail],
+                    _acc) ->
+    _els = encode_vcard_adr_ADR_HOME(Home,
+                                    encode_vcard_adr_ADR_WORK(Work,
+                                                              encode_vcard_adr_ADR_POSTAL(Postal,
+                                                                                          encode_vcard_adr_ADR_PARCEL(Parcel,
+                                                                                                                      encode_vcard_adr_ADR_DOM(Dom,
+                                                                                                                                               encode_vcard_adr_ADR_INTL(Intl,
+                                                                                                                                                                         encode_vcard_adr_ADR_PREF(Pref,
+                                                                                                                                                                                                   encode_vcard_adr_ADR_POBOX(Pobox,
+                                                                                                                                                                                                                              encode_vcard_adr_ADR_EXTADD(Extadd,
+                                                                                                                                                                                                                                                          encode_vcard_adr_ADR_STREET(Street,
+                                                                                                                                                                                                                                                                                      encode_vcard_adr_ADR_LOCALITY(Locality,
+                                                                                                                                                                                                                                                                                                                    encode_vcard_adr_ADR_REGION(Region,
+                                                                                                                                                                                                                                                                                                                                                encode_vcard_adr_ADR_PCODE(Pcode,
+                                                                                                                                                                                                                                                                                                                                                                           encode_vcard_adr_ADR_CTRY(Ctry,
+                                                                                                                                                                                                                                                                                                                                                                                                     [])))))))))))))),
+    _attrs = [],
+    encode_vcard_adr_ADR(_tail,
+                        [{xmlel, <<"ADR">>, _attrs, _els} | _acc]).
+
+decode_vcard_adr_ADR_CTRY({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_adr_ADR_CTRY_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_adr_ADR_CTRY_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_vcard_adr_ADR_CTRY_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_vcard_adr_ADR_CTRY_els([_ | _els], Cdata) ->
+    decode_vcard_adr_ADR_CTRY_els(_els, Cdata);
+decode_vcard_adr_ADR_CTRY_els([], Cdata) ->
+    decode_vcard_adr_ADR_CTRY_cdata(Cdata).
+
+encode_vcard_adr_ADR_CTRY(undefined, _acc) -> _acc;
+encode_vcard_adr_ADR_CTRY(Cdata, _acc) ->
+    _els = encode_vcard_adr_ADR_CTRY_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"CTRY">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_CTRY_cdata(<<>>) -> undefined;
+decode_vcard_adr_ADR_CTRY_cdata(_val) -> _val.
+
+encode_vcard_adr_ADR_CTRY_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_adr_ADR_CTRY_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR_PCODE({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_adr_ADR_PCODE_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_adr_ADR_PCODE_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_adr_ADR_PCODE_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_adr_ADR_PCODE_els([_ | _els], Cdata) ->
+    decode_vcard_adr_ADR_PCODE_els(_els, Cdata);
+decode_vcard_adr_ADR_PCODE_els([], Cdata) ->
+    decode_vcard_adr_ADR_PCODE_cdata(Cdata).
+
+encode_vcard_adr_ADR_PCODE(undefined, _acc) -> _acc;
+encode_vcard_adr_ADR_PCODE(Cdata, _acc) ->
+    _els = encode_vcard_adr_ADR_PCODE_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"PCODE">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_PCODE_cdata(<<>>) -> undefined;
+decode_vcard_adr_ADR_PCODE_cdata(_val) -> _val.
+
+encode_vcard_adr_ADR_PCODE_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_adr_ADR_PCODE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR_REGION({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_adr_ADR_REGION_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_adr_ADR_REGION_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_vcard_adr_ADR_REGION_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_vcard_adr_ADR_REGION_els([_ | _els], Cdata) ->
+    decode_vcard_adr_ADR_REGION_els(_els, Cdata);
+decode_vcard_adr_ADR_REGION_els([], Cdata) ->
+    decode_vcard_adr_ADR_REGION_cdata(Cdata).
+
+encode_vcard_adr_ADR_REGION(undefined, _acc) -> _acc;
+encode_vcard_adr_ADR_REGION(Cdata, _acc) ->
+    _els = encode_vcard_adr_ADR_REGION_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"REGION">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_REGION_cdata(<<>>) -> undefined;
+decode_vcard_adr_ADR_REGION_cdata(_val) -> _val.
+
+encode_vcard_adr_ADR_REGION_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_adr_ADR_REGION_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR_LOCALITY({xmlel, _, _attrs,
+                              _els}) ->
+    Cdata = decode_vcard_adr_ADR_LOCALITY_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_adr_ADR_LOCALITY_els([{xmlcdata, _data}
+                                  | _els],
+                                 Cdata) ->
+    decode_vcard_adr_ADR_LOCALITY_els(_els,
+                                     <<Cdata/binary, _data/binary>>);
+decode_vcard_adr_ADR_LOCALITY_els([_ | _els], Cdata) ->
+    decode_vcard_adr_ADR_LOCALITY_els(_els, Cdata);
+decode_vcard_adr_ADR_LOCALITY_els([], Cdata) ->
+    decode_vcard_adr_ADR_LOCALITY_cdata(Cdata).
+
+encode_vcard_adr_ADR_LOCALITY(undefined, _acc) -> _acc;
+encode_vcard_adr_ADR_LOCALITY(Cdata, _acc) ->
+    _els = encode_vcard_adr_ADR_LOCALITY_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"LOCALITY">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_LOCALITY_cdata(<<>>) -> undefined;
+decode_vcard_adr_ADR_LOCALITY_cdata(_val) -> _val.
+
+encode_vcard_adr_ADR_LOCALITY_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_adr_ADR_LOCALITY_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR_STREET({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_adr_ADR_STREET_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_adr_ADR_STREET_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_vcard_adr_ADR_STREET_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_vcard_adr_ADR_STREET_els([_ | _els], Cdata) ->
+    decode_vcard_adr_ADR_STREET_els(_els, Cdata);
+decode_vcard_adr_ADR_STREET_els([], Cdata) ->
+    decode_vcard_adr_ADR_STREET_cdata(Cdata).
+
+encode_vcard_adr_ADR_STREET(undefined, _acc) -> _acc;
+encode_vcard_adr_ADR_STREET(Cdata, _acc) ->
+    _els = encode_vcard_adr_ADR_STREET_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"STREET">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_STREET_cdata(<<>>) -> undefined;
+decode_vcard_adr_ADR_STREET_cdata(_val) -> _val.
+
+encode_vcard_adr_ADR_STREET_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_adr_ADR_STREET_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR_EXTADD({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_adr_ADR_EXTADD_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_adr_ADR_EXTADD_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_vcard_adr_ADR_EXTADD_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_vcard_adr_ADR_EXTADD_els([_ | _els], Cdata) ->
+    decode_vcard_adr_ADR_EXTADD_els(_els, Cdata);
+decode_vcard_adr_ADR_EXTADD_els([], Cdata) ->
+    decode_vcard_adr_ADR_EXTADD_cdata(Cdata).
+
+encode_vcard_adr_ADR_EXTADD(undefined, _acc) -> _acc;
+encode_vcard_adr_ADR_EXTADD(Cdata, _acc) ->
+    _els = encode_vcard_adr_ADR_EXTADD_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"EXTADD">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_EXTADD_cdata(<<>>) -> undefined;
+decode_vcard_adr_ADR_EXTADD_cdata(_val) -> _val.
+
+encode_vcard_adr_ADR_EXTADD_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_adr_ADR_EXTADD_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR_POBOX({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_adr_ADR_POBOX_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_adr_ADR_POBOX_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_adr_ADR_POBOX_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_adr_ADR_POBOX_els([_ | _els], Cdata) ->
+    decode_vcard_adr_ADR_POBOX_els(_els, Cdata);
+decode_vcard_adr_ADR_POBOX_els([], Cdata) ->
+    decode_vcard_adr_ADR_POBOX_cdata(Cdata).
+
+encode_vcard_adr_ADR_POBOX(undefined, _acc) -> _acc;
+encode_vcard_adr_ADR_POBOX(Cdata, _acc) ->
+    _els = encode_vcard_adr_ADR_POBOX_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"POBOX">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_POBOX_cdata(<<>>) -> undefined;
+decode_vcard_adr_ADR_POBOX_cdata(_val) -> _val.
+
+encode_vcard_adr_ADR_POBOX_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_adr_ADR_POBOX_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_adr_ADR_PREF({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_adr_ADR_PREF(false, _acc) -> _acc;
+encode_vcard_adr_ADR_PREF(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PREF">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_INTL({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_adr_ADR_INTL(false, _acc) -> _acc;
+encode_vcard_adr_ADR_INTL(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"INTL">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_DOM({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_adr_ADR_DOM(false, _acc) -> _acc;
+encode_vcard_adr_ADR_DOM(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"DOM">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_PARCEL({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_adr_ADR_PARCEL(false, _acc) -> _acc;
+encode_vcard_adr_ADR_PARCEL(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PARCEL">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_POSTAL({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_adr_ADR_POSTAL(false, _acc) -> _acc;
+encode_vcard_adr_ADR_POSTAL(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"POSTAL">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_WORK({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_adr_ADR_WORK(false, _acc) -> _acc;
+encode_vcard_adr_ADR_WORK(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"WORK">>, _attrs, _els} | _acc].
+
+decode_vcard_adr_ADR_HOME({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_adr_ADR_HOME(false, _acc) -> _acc;
+encode_vcard_adr_ADR_HOME(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"HOME">>, _attrs, _els} | _acc].
+
+decode_vcard_label_LABEL({xmlel, _, _attrs, _els}) ->
+    {Line, Pref, Intl, Dom, Parcel, Postal, Work, Home} =
+       decode_vcard_label_LABEL_els(_els, [], false, false,
+                                    false, false, false, false, false),
+    {vcard_label, Home, Work, Postal, Parcel, Dom, Intl,
+     Pref, Line}.
+
+decode_vcard_label_LABEL_els([{xmlel, <<"LINE">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els,
+                                      [decode_vcard_label_LABEL_LINE(_el)
+                                       | Line],
+                                      Pref, Intl, Dom, Parcel, Postal, Work,
+                                      Home);
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([{xmlel, <<"PREF">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els, Line,
+                                      decode_vcard_label_LABEL_PREF(_el), Intl,
+                                      Dom, Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([{xmlel, <<"INTL">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref,
+                                      decode_vcard_label_LABEL_INTL(_el), Dom,
+                                      Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([{xmlel, <<"DOM">>, _attrs,
+                              _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      decode_vcard_label_LABEL_DOM(_el),
+                                      Parcel, Postal, Work, Home);
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([{xmlel, <<"PARCEL">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom,
+                                      decode_vcard_label_LABEL_PARCEL(_el),
+                                      Postal, Work, Home);
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([{xmlel, <<"POSTAL">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel,
+                                      decode_vcard_label_LABEL_POSTAL(_el),
+                                      Work, Home);
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([{xmlel, <<"WORK">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal,
+                                      decode_vcard_label_LABEL_WORK(_el),
+                                      Home);
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([{xmlel, <<"HOME">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Line, Pref, Intl, Dom, Parcel, Postal, Work,
+                            Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work,
+                                      decode_vcard_label_LABEL_HOME(_el));
+      _ ->
+         decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                      Dom, Parcel, Postal, Work, Home)
+    end;
+decode_vcard_label_LABEL_els([_ | _els], Line, Pref,
+                            Intl, Dom, Parcel, Postal, Work, Home) ->
+    decode_vcard_label_LABEL_els(_els, Line, Pref, Intl,
+                                Dom, Parcel, Postal, Work, Home);
+decode_vcard_label_LABEL_els([], Line, Pref, Intl, Dom,
+                            Parcel, Postal, Work, Home) ->
+    {lists:reverse(Line), Pref, Intl, Dom, Parcel, Postal,
+     Work, Home}.
+
+encode_vcard_label_LABEL([], _acc) -> _acc;
+encode_vcard_label_LABEL([{vcard_label, Home, Work,
+                          Postal, Parcel, Dom, Intl, Pref, Line}
+                         | _tail],
+                        _acc) ->
+    _els = encode_vcard_label_LABEL_HOME(Home,
+                                        encode_vcard_label_LABEL_WORK(Work,
+                                                                      encode_vcard_label_LABEL_POSTAL(Postal,
+                                                                                                      encode_vcard_label_LABEL_PARCEL(Parcel,
+                                                                                                                                      encode_vcard_label_LABEL_DOM(Dom,
+                                                                                                                                                                   encode_vcard_label_LABEL_INTL(Intl,
+                                                                                                                                                                                                 encode_vcard_label_LABEL_PREF(Pref,
+                                                                                                                                                                                                                               encode_vcard_label_LABEL_LINE(Line,
+                                                                                                                                                                                                                                                             [])))))))),
+    _attrs = [],
+    encode_vcard_label_LABEL(_tail,
+                            [{xmlel, <<"LABEL">>, _attrs, _els} | _acc]).
+
+decode_vcard_label_LABEL_LINE({xmlel, _, _attrs,
+                              _els}) ->
+    Cdata = decode_vcard_label_LABEL_LINE_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_label_LABEL_LINE_els([{xmlcdata, _data}
+                                  | _els],
+                                 Cdata) ->
+    decode_vcard_label_LABEL_LINE_els(_els,
+                                     <<Cdata/binary, _data/binary>>);
+decode_vcard_label_LABEL_LINE_els([_ | _els], Cdata) ->
+    decode_vcard_label_LABEL_LINE_els(_els, Cdata);
+decode_vcard_label_LABEL_LINE_els([], Cdata) ->
+    decode_vcard_label_LABEL_LINE_cdata(Cdata).
+
+encode_vcard_label_LABEL_LINE([], _acc) -> _acc;
+encode_vcard_label_LABEL_LINE([Cdata | _tail], _acc) ->
+    _els = encode_vcard_label_LABEL_LINE_cdata(Cdata, []),
+    _attrs = [],
+    encode_vcard_label_LABEL_LINE(_tail,
+                                 [{xmlel, <<"LINE">>, _attrs, _els} | _acc]).
+
+decode_vcard_label_LABEL_LINE_cdata(<<>>) -> undefined;
+decode_vcard_label_LABEL_LINE_cdata(_val) -> _val.
+
+encode_vcard_label_LABEL_LINE_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_label_LABEL_LINE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_label_LABEL_PREF({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_label_LABEL_PREF(false, _acc) -> _acc;
+encode_vcard_label_LABEL_PREF(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PREF">>, _attrs, _els} | _acc].
+
+decode_vcard_label_LABEL_INTL({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_label_LABEL_INTL(false, _acc) -> _acc;
+encode_vcard_label_LABEL_INTL(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"INTL">>, _attrs, _els} | _acc].
+
+decode_vcard_label_LABEL_DOM({xmlel, _, _attrs,
+                             _els}) ->
+    true.
+
+encode_vcard_label_LABEL_DOM(false, _acc) -> _acc;
+encode_vcard_label_LABEL_DOM(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"DOM">>, _attrs, _els} | _acc].
+
+decode_vcard_label_LABEL_PARCEL({xmlel, _, _attrs,
+                                _els}) ->
+    true.
+
+encode_vcard_label_LABEL_PARCEL(false, _acc) -> _acc;
+encode_vcard_label_LABEL_PARCEL(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PARCEL">>, _attrs, _els} | _acc].
+
+decode_vcard_label_LABEL_POSTAL({xmlel, _, _attrs,
+                                _els}) ->
+    true.
+
+encode_vcard_label_LABEL_POSTAL(false, _acc) -> _acc;
+encode_vcard_label_LABEL_POSTAL(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"POSTAL">>, _attrs, _els} | _acc].
+
+decode_vcard_label_LABEL_WORK({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_label_LABEL_WORK(false, _acc) -> _acc;
+encode_vcard_label_LABEL_WORK(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"WORK">>, _attrs, _els} | _acc].
+
+decode_vcard_label_LABEL_HOME({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_label_LABEL_HOME(false, _acc) -> _acc;
+encode_vcard_label_LABEL_HOME(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"HOME">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL({xmlel, _, _attrs, _els}) ->
+    {Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+     Pager, Fax, Voice, Work, Home} =
+       decode_vcard_tel_TEL_els(_els, [], false, false, false,
+                                false, false, false, false, false, false,
+                                false, false, false, false),
+    {vcard_tel, Home, Work, Voice, Fax, Pager, Msg, Cell,
+     Video, Bbs, Modem, Isdn, Pcs, Pref, Number}.
+
+decode_vcard_tel_TEL_els([{xmlel, <<"NUMBER">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els,
+                                  [decode_vcard_tel_TEL_NUMBER(_el) | Number],
+                                  Pref, Pcs, Isdn, Modem, Bbs, Video, Cell,
+                                  Msg, Pager, Fax, Voice, Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"PREF">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number,
+                                  decode_vcard_tel_TEL_PREF(_el), Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"PCS">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref,
+                                  decode_vcard_tel_TEL_PCS(_el), Isdn, Modem,
+                                  Bbs, Video, Cell, Msg, Pager, Fax, Voice,
+                                  Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"ISDN">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs,
+                                  decode_vcard_tel_TEL_ISDN(_el), Modem, Bbs,
+                                  Video, Cell, Msg, Pager, Fax, Voice, Work,
+                                  Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"MODEM">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  decode_vcard_tel_TEL_MODEM(_el), Bbs, Video,
+                                  Cell, Msg, Pager, Fax, Voice, Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"BBS">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, decode_vcard_tel_TEL_BBS(_el), Video,
+                                  Cell, Msg, Pager, Fax, Voice, Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"VIDEO">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, decode_vcard_tel_TEL_VIDEO(_el),
+                                  Cell, Msg, Pager, Fax, Voice, Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"CELL">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video,
+                                  decode_vcard_tel_TEL_CELL(_el), Msg, Pager,
+                                  Fax, Voice, Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"MSG">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell,
+                                  decode_vcard_tel_TEL_MSG(_el), Pager, Fax,
+                                  Voice, Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"PAGER">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg,
+                                  decode_vcard_tel_TEL_PAGER(_el), Fax, Voice,
+                                  Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"FAX">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager,
+                                  decode_vcard_tel_TEL_FAX(_el), Voice, Work,
+                                  Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"VOICE">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  decode_vcard_tel_TEL_VOICE(_el), Work, Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"WORK">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, decode_vcard_tel_TEL_WORK(_el), Home);
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([{xmlel, <<"HOME">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+                        Pager, Fax, Voice, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, decode_vcard_tel_TEL_HOME(_el));
+      _ ->
+         decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                                  Modem, Bbs, Video, Cell, Msg, Pager, Fax,
+                                  Voice, Work, Home)
+    end;
+decode_vcard_tel_TEL_els([_ | _els], Number, Pref, Pcs,
+                        Isdn, Modem, Bbs, Video, Cell, Msg, Pager, Fax, Voice,
+                        Work, Home) ->
+    decode_vcard_tel_TEL_els(_els, Number, Pref, Pcs, Isdn,
+                            Modem, Bbs, Video, Cell, Msg, Pager, Fax, Voice,
+                            Work, Home);
+decode_vcard_tel_TEL_els([], [Number], Pref, Pcs, Isdn,
+                        Modem, Bbs, Video, Cell, Msg, Pager, Fax, Voice, Work,
+                        Home) ->
+    {Number, Pref, Pcs, Isdn, Modem, Bbs, Video, Cell, Msg,
+     Pager, Fax, Voice, Work, Home}.
+
+encode_vcard_tel_TEL([], _acc) -> _acc;
+encode_vcard_tel_TEL([{vcard_tel, Home, Work, Voice,
+                      Fax, Pager, Msg, Cell, Video, Bbs, Modem, Isdn, Pcs,
+                      Pref, Number}
+                     | _tail],
+                    _acc) ->
+    _els = encode_vcard_tel_TEL_HOME(Home,
+                                    encode_vcard_tel_TEL_WORK(Work,
+                                                              encode_vcard_tel_TEL_VOICE(Voice,
+                                                                                         encode_vcard_tel_TEL_FAX(Fax,
+                                                                                                                  encode_vcard_tel_TEL_PAGER(Pager,
+                                                                                                                                             encode_vcard_tel_TEL_MSG(Msg,
+                                                                                                                                                                      encode_vcard_tel_TEL_CELL(Cell,
+                                                                                                                                                                                                encode_vcard_tel_TEL_VIDEO(Video,
+                                                                                                                                                                                                                           encode_vcard_tel_TEL_BBS(Bbs,
+                                                                                                                                                                                                                                                    encode_vcard_tel_TEL_MODEM(Modem,
+                                                                                                                                                                                                                                                                               encode_vcard_tel_TEL_ISDN(Isdn,
+                                                                                                                                                                                                                                                                                                         encode_vcard_tel_TEL_PCS(Pcs,
+                                                                                                                                                                                                                                                                                                                                  encode_vcard_tel_TEL_PREF(Pref,
+                                                                                                                                                                                                                                                                                                                                                            encode_vcard_tel_TEL_NUMBER(Number,
+                                                                                                                                                                                                                                                                                                                                                                                        [])))))))))))))),
+    _attrs = [],
+    encode_vcard_tel_TEL(_tail,
+                        [{xmlel, <<"TEL">>, _attrs, _els} | _acc]).
+
+decode_vcard_tel_TEL_NUMBER({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_tel_TEL_NUMBER_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_tel_TEL_NUMBER_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_vcard_tel_TEL_NUMBER_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_vcard_tel_TEL_NUMBER_els([_ | _els], Cdata) ->
+    decode_vcard_tel_TEL_NUMBER_els(_els, Cdata);
+decode_vcard_tel_TEL_NUMBER_els([], Cdata) ->
+    decode_vcard_tel_TEL_NUMBER_cdata(Cdata).
+
+encode_vcard_tel_TEL_NUMBER(Cdata, _acc) ->
+    _els = encode_vcard_tel_TEL_NUMBER_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"NUMBER">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_NUMBER_cdata(<<>>) -> undefined;
+decode_vcard_tel_TEL_NUMBER_cdata(_val) -> _val.
+
+encode_vcard_tel_TEL_NUMBER_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_tel_TEL_NUMBER_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_tel_TEL_PREF({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_PREF(false, _acc) -> _acc;
+encode_vcard_tel_TEL_PREF(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PREF">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_PCS({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_PCS(false, _acc) -> _acc;
+encode_vcard_tel_TEL_PCS(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PCS">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_ISDN({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_ISDN(false, _acc) -> _acc;
+encode_vcard_tel_TEL_ISDN(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"ISDN">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_MODEM({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_MODEM(false, _acc) -> _acc;
+encode_vcard_tel_TEL_MODEM(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"MODEM">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_BBS({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_BBS(false, _acc) -> _acc;
+encode_vcard_tel_TEL_BBS(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"BBS">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_VIDEO({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_VIDEO(false, _acc) -> _acc;
+encode_vcard_tel_TEL_VIDEO(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"VIDEO">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_CELL({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_CELL(false, _acc) -> _acc;
+encode_vcard_tel_TEL_CELL(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"CELL">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_MSG({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_MSG(false, _acc) -> _acc;
+encode_vcard_tel_TEL_MSG(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"MSG">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_PAGER({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_PAGER(false, _acc) -> _acc;
+encode_vcard_tel_TEL_PAGER(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PAGER">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_FAX({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_FAX(false, _acc) -> _acc;
+encode_vcard_tel_TEL_FAX(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"FAX">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_VOICE({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_VOICE(false, _acc) -> _acc;
+encode_vcard_tel_TEL_VOICE(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"VOICE">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_WORK({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_WORK(false, _acc) -> _acc;
+encode_vcard_tel_TEL_WORK(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"WORK">>, _attrs, _els} | _acc].
+
+decode_vcard_tel_TEL_HOME({xmlel, _, _attrs, _els}) ->
+    true.
+
+encode_vcard_tel_TEL_HOME(false, _acc) -> _acc;
+encode_vcard_tel_TEL_HOME(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"HOME">>, _attrs, _els} | _acc].
+
+decode_vcard_email_EMAIL({xmlel, _, _attrs, _els}) ->
+    {Userid, X400, Pref, Internet, Work, Home} =
+       decode_vcard_email_EMAIL_els(_els, [], false, false,
+                                    false, false, false),
+    {vcard_email, Home, Work, Internet, Pref, X400, Userid}.
+
+decode_vcard_email_EMAIL_els([{xmlel, <<"USERID">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Userid, X400, Pref, Internet, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_email_EMAIL_els(_els,
+                                      [decode_vcard_email_EMAIL_USERID(_el)
+                                       | Userid],
+                                      X400, Pref, Internet, Work, Home);
+      _ ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet, Work, Home)
+    end;
+decode_vcard_email_EMAIL_els([{xmlel, <<"X400">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Userid, X400, Pref, Internet, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_email_EMAIL_els(_els, Userid,
+                                      decode_vcard_email_EMAIL_X400(_el), Pref,
+                                      Internet, Work, Home);
+      _ ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet, Work, Home)
+    end;
+decode_vcard_email_EMAIL_els([{xmlel, <<"PREF">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Userid, X400, Pref, Internet, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400,
+                                      decode_vcard_email_EMAIL_PREF(_el),
+                                      Internet, Work, Home);
+      _ ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet, Work, Home)
+    end;
+decode_vcard_email_EMAIL_els([{xmlel, <<"INTERNET">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Userid, X400, Pref, Internet, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      decode_vcard_email_EMAIL_INTERNET(_el),
+                                      Work, Home);
+      _ ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet, Work, Home)
+    end;
+decode_vcard_email_EMAIL_els([{xmlel, <<"WORK">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Userid, X400, Pref, Internet, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet,
+                                      decode_vcard_email_EMAIL_WORK(_el),
+                                      Home);
+      _ ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet, Work, Home)
+    end;
+decode_vcard_email_EMAIL_els([{xmlel, <<"HOME">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Userid, X400, Pref, Internet, Work, Home) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet, Work,
+                                      decode_vcard_email_EMAIL_HOME(_el));
+      _ ->
+         decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                      Internet, Work, Home)
+    end;
+decode_vcard_email_EMAIL_els([_ | _els], Userid, X400,
+                            Pref, Internet, Work, Home) ->
+    decode_vcard_email_EMAIL_els(_els, Userid, X400, Pref,
+                                Internet, Work, Home);
+decode_vcard_email_EMAIL_els([], [Userid], X400, Pref,
+                            Internet, Work, Home) ->
+    {Userid, X400, Pref, Internet, Work, Home}.
+
+encode_vcard_email_EMAIL([], _acc) -> _acc;
+encode_vcard_email_EMAIL([{vcard_email, Home, Work,
+                          Internet, Pref, X400, Userid}
+                         | _tail],
+                        _acc) ->
+    _els = encode_vcard_email_EMAIL_HOME(Home,
+                                        encode_vcard_email_EMAIL_WORK(Work,
+                                                                      encode_vcard_email_EMAIL_INTERNET(Internet,
+                                                                                                        encode_vcard_email_EMAIL_PREF(Pref,
+                                                                                                                                      encode_vcard_email_EMAIL_X400(X400,
+                                                                                                                                                                    encode_vcard_email_EMAIL_USERID(Userid,
+                                                                                                                                                                                                    [])))))),
+    _attrs = [],
+    encode_vcard_email_EMAIL(_tail,
+                            [{xmlel, <<"EMAIL">>, _attrs, _els} | _acc]).
+
+decode_vcard_email_EMAIL_USERID({xmlel, _, _attrs,
+                                _els}) ->
+    Cdata = decode_vcard_email_EMAIL_USERID_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_email_EMAIL_USERID_els([{xmlcdata, _data}
+                                    | _els],
+                                   Cdata) ->
+    decode_vcard_email_EMAIL_USERID_els(_els,
+                                       <<Cdata/binary, _data/binary>>);
+decode_vcard_email_EMAIL_USERID_els([_ | _els],
+                                   Cdata) ->
+    decode_vcard_email_EMAIL_USERID_els(_els, Cdata);
+decode_vcard_email_EMAIL_USERID_els([], Cdata) ->
+    decode_vcard_email_EMAIL_USERID_cdata(Cdata).
+
+encode_vcard_email_EMAIL_USERID(Cdata, _acc) ->
+    _els = encode_vcard_email_EMAIL_USERID_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"USERID">>, _attrs, _els} | _acc].
+
+decode_vcard_email_EMAIL_USERID_cdata(<<>>) ->
+    undefined;
+decode_vcard_email_EMAIL_USERID_cdata(_val) -> _val.
+
+encode_vcard_email_EMAIL_USERID_cdata(undefined,
+                                     _acc) ->
+    _acc;
+encode_vcard_email_EMAIL_USERID_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_email_EMAIL_X400({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_email_EMAIL_X400(false, _acc) -> _acc;
+encode_vcard_email_EMAIL_X400(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"X400">>, _attrs, _els} | _acc].
+
+decode_vcard_email_EMAIL_PREF({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_email_EMAIL_PREF(false, _acc) -> _acc;
+encode_vcard_email_EMAIL_PREF(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PREF">>, _attrs, _els} | _acc].
+
+decode_vcard_email_EMAIL_INTERNET({xmlel, _, _attrs,
+                                  _els}) ->
+    true.
+
+encode_vcard_email_EMAIL_INTERNET(false, _acc) -> _acc;
+encode_vcard_email_EMAIL_INTERNET(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"INTERNET">>, _attrs, _els} | _acc].
+
+decode_vcard_email_EMAIL_WORK({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_email_EMAIL_WORK(false, _acc) -> _acc;
+encode_vcard_email_EMAIL_WORK(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"WORK">>, _attrs, _els} | _acc].
+
+decode_vcard_email_EMAIL_HOME({xmlel, _, _attrs,
+                              _els}) ->
+    true.
+
+encode_vcard_email_EMAIL_HOME(false, _acc) -> _acc;
+encode_vcard_email_EMAIL_HOME(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"HOME">>, _attrs, _els} | _acc].
+
+decode_vcard_geo_GEO({xmlel, _, _attrs, _els}) ->
+    {Lon, Lat} = decode_vcard_geo_GEO_els(_els, [], []),
+    {vcard_geo, Lat, Lon}.
+
+decode_vcard_geo_GEO_els([{xmlel, <<"LON">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Lon, Lat) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_geo_GEO_els(_els,
+                                  [decode_vcard_geo_GEO_LON(_el) | Lon], Lat);
+      _ -> decode_vcard_geo_GEO_els(_els, Lon, Lat)
+    end;
+decode_vcard_geo_GEO_els([{xmlel, <<"LAT">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Lon, Lat) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_geo_GEO_els(_els, Lon,
+                                  [decode_vcard_geo_GEO_LAT(_el) | Lat]);
+      _ -> decode_vcard_geo_GEO_els(_els, Lon, Lat)
+    end;
+decode_vcard_geo_GEO_els([_ | _els], Lon, Lat) ->
+    decode_vcard_geo_GEO_els(_els, Lon, Lat);
+decode_vcard_geo_GEO_els([], [Lon], [Lat]) ->
+    {Lon, Lat}.
+
+encode_vcard_geo_GEO(undefined, _acc) -> _acc;
+encode_vcard_geo_GEO({vcard_geo, Lat, Lon}, _acc) ->
+    _els = encode_vcard_geo_GEO_LAT(Lat,
+                                   encode_vcard_geo_GEO_LON(Lon, [])),
+    _attrs = [],
+    [{xmlel, <<"GEO">>, _attrs, _els} | _acc].
+
+decode_vcard_geo_GEO_LON({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_geo_GEO_LON_els(_els, <<>>), Cdata.
+
+decode_vcard_geo_GEO_LON_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_vcard_geo_GEO_LON_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_vcard_geo_GEO_LON_els([_ | _els], Cdata) ->
+    decode_vcard_geo_GEO_LON_els(_els, Cdata);
+decode_vcard_geo_GEO_LON_els([], Cdata) ->
+    decode_vcard_geo_GEO_LON_cdata(Cdata).
+
+encode_vcard_geo_GEO_LON(Cdata, _acc) ->
+    _els = encode_vcard_geo_GEO_LON_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"LON">>, _attrs, _els} | _acc].
+
+decode_vcard_geo_GEO_LON_cdata(<<>>) -> undefined;
+decode_vcard_geo_GEO_LON_cdata(_val) -> _val.
+
+encode_vcard_geo_GEO_LON_cdata(undefined, _acc) -> _acc;
+encode_vcard_geo_GEO_LON_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_geo_GEO_LAT({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_geo_GEO_LAT_els(_els, <<>>), Cdata.
+
+decode_vcard_geo_GEO_LAT_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_vcard_geo_GEO_LAT_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_vcard_geo_GEO_LAT_els([_ | _els], Cdata) ->
+    decode_vcard_geo_GEO_LAT_els(_els, Cdata);
+decode_vcard_geo_GEO_LAT_els([], Cdata) ->
+    decode_vcard_geo_GEO_LAT_cdata(Cdata).
+
+encode_vcard_geo_GEO_LAT(Cdata, _acc) ->
+    _els = encode_vcard_geo_GEO_LAT_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"LAT">>, _attrs, _els} | _acc].
+
+decode_vcard_geo_GEO_LAT_cdata(<<>>) -> undefined;
+decode_vcard_geo_GEO_LAT_cdata(_val) -> _val.
+
+encode_vcard_geo_GEO_LAT_cdata(undefined, _acc) -> _acc;
+encode_vcard_geo_GEO_LAT_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_type_TYPE({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_type_TYPE_els(_els, <<>>), Cdata.
+
+decode_vcard_type_TYPE_els([{xmlcdata, _data} | _els],
+                          Cdata) ->
+    decode_vcard_type_TYPE_els(_els,
+                              <<Cdata/binary, _data/binary>>);
+decode_vcard_type_TYPE_els([_ | _els], Cdata) ->
+    decode_vcard_type_TYPE_els(_els, Cdata);
+decode_vcard_type_TYPE_els([], Cdata) ->
+    decode_vcard_type_TYPE_cdata(Cdata).
+
+encode_vcard_type_TYPE(undefined, _acc) -> _acc;
+encode_vcard_type_TYPE(Cdata, _acc) ->
+    _els = encode_vcard_type_TYPE_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"TYPE">>, _attrs, _els} | _acc].
+
+decode_vcard_type_TYPE_cdata(<<>>) -> undefined;
+decode_vcard_type_TYPE_cdata(_val) -> _val.
+
+encode_vcard_type_TYPE_cdata(undefined, _acc) -> _acc;
+encode_vcard_type_TYPE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_binval_BINVAL({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_binval_BINVAL_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_binval_BINVAL_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_binval_BINVAL_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_binval_BINVAL_els([_ | _els], Cdata) ->
+    decode_vcard_binval_BINVAL_els(_els, Cdata);
+decode_vcard_binval_BINVAL_els([], Cdata) ->
+    decode_vcard_binval_BINVAL_cdata(Cdata).
+
+encode_vcard_binval_BINVAL(undefined, _acc) -> _acc;
+encode_vcard_binval_BINVAL(Cdata, _acc) ->
+    _els = encode_vcard_binval_BINVAL_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"BINVAL">>, _attrs, _els} | _acc].
+
+decode_vcard_binval_BINVAL_cdata(<<>>) -> undefined;
+decode_vcard_binval_BINVAL_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"BINVAL">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_vcard_binval_BINVAL_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_binval_BINVAL_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
+
+decode_vcard_extval_EXTVAL({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_extval_EXTVAL_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_extval_EXTVAL_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_extval_EXTVAL_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_extval_EXTVAL_els([_ | _els], Cdata) ->
+    decode_vcard_extval_EXTVAL_els(_els, Cdata);
+decode_vcard_extval_EXTVAL_els([], Cdata) ->
+    decode_vcard_extval_EXTVAL_cdata(Cdata).
+
+encode_vcard_extval_EXTVAL(undefined, _acc) -> _acc;
+encode_vcard_extval_EXTVAL(Cdata, _acc) ->
+    _els = encode_vcard_extval_EXTVAL_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"EXTVAL">>, _attrs, _els} | _acc].
+
+decode_vcard_extval_EXTVAL_cdata(<<>>) -> undefined;
+decode_vcard_extval_EXTVAL_cdata(_val) -> _val.
+
+encode_vcard_extval_EXTVAL_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_extval_EXTVAL_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_logo_LOGO({xmlel, _, _attrs, _els}) ->
+    {Extval, Binval, Type} =
+       decode_vcard_logo_LOGO_els(_els, undefined, undefined,
+                                  undefined),
+    {vcard_logo, Type, Binval, Extval}.
+
+decode_vcard_logo_LOGO_els([{xmlel, <<"EXTVAL">>,
+                            _attrs, _} =
+                               _el
+                           | _els],
+                          Extval, Binval, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_logo_LOGO_els(_els,
+                                    decode_vcard_extval_EXTVAL(_el), Binval,
+                                    Type);
+      _ ->
+         decode_vcard_logo_LOGO_els(_els, Extval, Binval, Type)
+    end;
+decode_vcard_logo_LOGO_els([{xmlel, <<"BINVAL">>,
+                            _attrs, _} =
+                               _el
+                           | _els],
+                          Extval, Binval, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_logo_LOGO_els(_els, Extval,
+                                    decode_vcard_binval_BINVAL(_el), Type);
+      _ ->
+         decode_vcard_logo_LOGO_els(_els, Extval, Binval, Type)
+    end;
+decode_vcard_logo_LOGO_els([{xmlel, <<"TYPE">>, _attrs,
+                            _} =
+                               _el
+                           | _els],
+                          Extval, Binval, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_logo_LOGO_els(_els, Extval, Binval,
+                                    decode_vcard_type_TYPE(_el));
+      _ ->
+         decode_vcard_logo_LOGO_els(_els, Extval, Binval, Type)
+    end;
+decode_vcard_logo_LOGO_els([_ | _els], Extval, Binval,
+                          Type) ->
+    decode_vcard_logo_LOGO_els(_els, Extval, Binval, Type);
+decode_vcard_logo_LOGO_els([], Extval, Binval, Type) ->
+    {Extval, Binval, Type}.
+
+encode_vcard_logo_LOGO(undefined, _acc) -> _acc;
+encode_vcard_logo_LOGO({vcard_logo, Type, Binval,
+                       Extval},
+                      _acc) ->
+    _els = encode_vcard_type_TYPE(Type,
+                                 encode_vcard_binval_BINVAL(Binval,
+                                                            encode_vcard_extval_EXTVAL(Extval,
+                                                                                       []))),
+    _attrs = [],
+    [{xmlel, <<"LOGO">>, _attrs, _els} | _acc].
+
+decode_vcard_photo_PHOTO({xmlel, _, _attrs, _els}) ->
+    {Extval, Binval, Type} =
+       decode_vcard_photo_PHOTO_els(_els, undefined, undefined,
+                                    undefined),
+    {vcard_photo, Type, Binval, Extval}.
+
+decode_vcard_photo_PHOTO_els([{xmlel, <<"EXTVAL">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Extval, Binval, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_photo_PHOTO_els(_els,
+                                      decode_vcard_extval_EXTVAL(_el), Binval,
+                                      Type);
+      _ ->
+         decode_vcard_photo_PHOTO_els(_els, Extval, Binval, Type)
+    end;
+decode_vcard_photo_PHOTO_els([{xmlel, <<"BINVAL">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Extval, Binval, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_photo_PHOTO_els(_els, Extval,
+                                      decode_vcard_binval_BINVAL(_el), Type);
+      _ ->
+         decode_vcard_photo_PHOTO_els(_els, Extval, Binval, Type)
+    end;
+decode_vcard_photo_PHOTO_els([{xmlel, <<"TYPE">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Extval, Binval, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_photo_PHOTO_els(_els, Extval, Binval,
+                                      decode_vcard_type_TYPE(_el));
+      _ ->
+         decode_vcard_photo_PHOTO_els(_els, Extval, Binval, Type)
+    end;
+decode_vcard_photo_PHOTO_els([_ | _els], Extval, Binval,
+                            Type) ->
+    decode_vcard_photo_PHOTO_els(_els, Extval, Binval,
+                                Type);
+decode_vcard_photo_PHOTO_els([], Extval, Binval,
+                            Type) ->
+    {Extval, Binval, Type}.
+
+encode_vcard_photo_PHOTO(undefined, _acc) -> _acc;
+encode_vcard_photo_PHOTO({vcard_photo, Type, Binval,
+                         Extval},
+                        _acc) ->
+    _els = encode_vcard_type_TYPE(Type,
+                                 encode_vcard_binval_BINVAL(Binval,
+                                                            encode_vcard_extval_EXTVAL(Extval,
+                                                                                       []))),
+    _attrs = [],
+    [{xmlel, <<"PHOTO">>, _attrs, _els} | _acc].
+
+decode_vcard_org_ORG({xmlel, _, _attrs, _els}) ->
+    {Units, Name} = decode_vcard_org_ORG_els(_els, [], []),
+    {vcard_org, Name, Units}.
+
+decode_vcard_org_ORG_els([{xmlel, <<"ORGUNIT">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Units, Name) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_org_ORG_els(_els,
+                                  [decode_vcard_org_ORG_ORGUNIT(_el) | Units],
+                                  Name);
+      _ -> decode_vcard_org_ORG_els(_els, Units, Name)
+    end;
+decode_vcard_org_ORG_els([{xmlel, <<"ORGNAME">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Units, Name) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_org_ORG_els(_els, Units,
+                                  [decode_vcard_org_ORG_ORGNAME(_el) | Name]);
+      _ -> decode_vcard_org_ORG_els(_els, Units, Name)
+    end;
+decode_vcard_org_ORG_els([_ | _els], Units, Name) ->
+    decode_vcard_org_ORG_els(_els, Units, Name);
+decode_vcard_org_ORG_els([], Units, [Name]) ->
+    {lists:reverse(Units), Name}.
+
+encode_vcard_org_ORG(undefined, _acc) -> _acc;
+encode_vcard_org_ORG({vcard_org, Name, Units}, _acc) ->
+    _els = encode_vcard_org_ORG_ORGNAME(Name,
+                                       encode_vcard_org_ORG_ORGUNIT(Units,
+                                                                    [])),
+    _attrs = [],
+    [{xmlel, <<"ORG">>, _attrs, _els} | _acc].
+
+decode_vcard_org_ORG_ORGUNIT({xmlel, _, _attrs,
+                             _els}) ->
+    Cdata = decode_vcard_org_ORG_ORGUNIT_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_org_ORG_ORGUNIT_els([{xmlcdata, _data}
+                                 | _els],
+                                Cdata) ->
+    decode_vcard_org_ORG_ORGUNIT_els(_els,
+                                    <<Cdata/binary, _data/binary>>);
+decode_vcard_org_ORG_ORGUNIT_els([_ | _els], Cdata) ->
+    decode_vcard_org_ORG_ORGUNIT_els(_els, Cdata);
+decode_vcard_org_ORG_ORGUNIT_els([], Cdata) ->
+    decode_vcard_org_ORG_ORGUNIT_cdata(Cdata).
+
+encode_vcard_org_ORG_ORGUNIT([], _acc) -> _acc;
+encode_vcard_org_ORG_ORGUNIT([Cdata | _tail], _acc) ->
+    _els = encode_vcard_org_ORG_ORGUNIT_cdata(Cdata, []),
+    _attrs = [],
+    encode_vcard_org_ORG_ORGUNIT(_tail,
+                                [{xmlel, <<"ORGUNIT">>, _attrs, _els} | _acc]).
+
+decode_vcard_org_ORG_ORGUNIT_cdata(<<>>) -> undefined;
+decode_vcard_org_ORG_ORGUNIT_cdata(_val) -> _val.
+
+encode_vcard_org_ORG_ORGUNIT_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_org_ORG_ORGUNIT_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_org_ORG_ORGNAME({xmlel, _, _attrs,
+                             _els}) ->
+    Cdata = decode_vcard_org_ORG_ORGNAME_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_org_ORG_ORGNAME_els([{xmlcdata, _data}
+                                 | _els],
+                                Cdata) ->
+    decode_vcard_org_ORG_ORGNAME_els(_els,
+                                    <<Cdata/binary, _data/binary>>);
+decode_vcard_org_ORG_ORGNAME_els([_ | _els], Cdata) ->
+    decode_vcard_org_ORG_ORGNAME_els(_els, Cdata);
+decode_vcard_org_ORG_ORGNAME_els([], Cdata) ->
+    decode_vcard_org_ORG_ORGNAME_cdata(Cdata).
+
+encode_vcard_org_ORG_ORGNAME(Cdata, _acc) ->
+    _els = encode_vcard_org_ORG_ORGNAME_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"ORGNAME">>, _attrs, _els} | _acc].
+
+decode_vcard_org_ORG_ORGNAME_cdata(<<>>) -> undefined;
+decode_vcard_org_ORG_ORGNAME_cdata(_val) -> _val.
+
+encode_vcard_org_ORG_ORGNAME_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_org_ORG_ORGNAME_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_sound_SOUND({xmlel, _, _attrs, _els}) ->
+    {Extval, Binval, Phonetic} =
+       decode_vcard_sound_SOUND_els(_els, undefined, undefined,
+                                    undefined),
+    {vcard_sound, Phonetic, Binval, Extval}.
+
+decode_vcard_sound_SOUND_els([{xmlel, <<"EXTVAL">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Extval, Binval, Phonetic) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_sound_SOUND_els(_els,
+                                      decode_vcard_extval_EXTVAL(_el), Binval,
+                                      Phonetic);
+      _ ->
+         decode_vcard_sound_SOUND_els(_els, Extval, Binval,
+                                      Phonetic)
+    end;
+decode_vcard_sound_SOUND_els([{xmlel, <<"BINVAL">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Extval, Binval, Phonetic) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_sound_SOUND_els(_els, Extval,
+                                      decode_vcard_binval_BINVAL(_el),
+                                      Phonetic);
+      _ ->
+         decode_vcard_sound_SOUND_els(_els, Extval, Binval,
+                                      Phonetic)
+    end;
+decode_vcard_sound_SOUND_els([{xmlel, <<"PHONETIC">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Extval, Binval, Phonetic) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_sound_SOUND_els(_els, Extval, Binval,
+                                      decode_vcard_sound_SOUND_PHONETIC(_el));
+      _ ->
+         decode_vcard_sound_SOUND_els(_els, Extval, Binval,
+                                      Phonetic)
+    end;
+decode_vcard_sound_SOUND_els([_ | _els], Extval, Binval,
+                            Phonetic) ->
+    decode_vcard_sound_SOUND_els(_els, Extval, Binval,
+                                Phonetic);
+decode_vcard_sound_SOUND_els([], Extval, Binval,
+                            Phonetic) ->
+    {Extval, Binval, Phonetic}.
+
+encode_vcard_sound_SOUND(undefined, _acc) -> _acc;
+encode_vcard_sound_SOUND({vcard_sound, Phonetic, Binval,
+                         Extval},
+                        _acc) ->
+    _els = encode_vcard_sound_SOUND_PHONETIC(Phonetic,
+                                            encode_vcard_binval_BINVAL(Binval,
+                                                                       encode_vcard_extval_EXTVAL(Extval,
+                                                                                                  []))),
+    _attrs = [],
+    [{xmlel, <<"SOUND">>, _attrs, _els} | _acc].
+
+decode_vcard_sound_SOUND_PHONETIC({xmlel, _, _attrs,
+                                  _els}) ->
+    Cdata = decode_vcard_sound_SOUND_PHONETIC_els(_els,
+                                                 <<>>),
+    Cdata.
+
+decode_vcard_sound_SOUND_PHONETIC_els([{xmlcdata, _data}
+                                      | _els],
+                                     Cdata) ->
+    decode_vcard_sound_SOUND_PHONETIC_els(_els,
+                                         <<Cdata/binary, _data/binary>>);
+decode_vcard_sound_SOUND_PHONETIC_els([_ | _els],
+                                     Cdata) ->
+    decode_vcard_sound_SOUND_PHONETIC_els(_els, Cdata);
+decode_vcard_sound_SOUND_PHONETIC_els([], Cdata) ->
+    decode_vcard_sound_SOUND_PHONETIC_cdata(Cdata).
+
+encode_vcard_sound_SOUND_PHONETIC(undefined, _acc) ->
+    _acc;
+encode_vcard_sound_SOUND_PHONETIC(Cdata, _acc) ->
+    _els = encode_vcard_sound_SOUND_PHONETIC_cdata(Cdata,
+                                                  []),
+    _attrs = [],
+    [{xmlel, <<"PHONETIC">>, _attrs, _els} | _acc].
+
+decode_vcard_sound_SOUND_PHONETIC_cdata(<<>>) ->
+    undefined;
+decode_vcard_sound_SOUND_PHONETIC_cdata(_val) -> _val.
+
+encode_vcard_sound_SOUND_PHONETIC_cdata(undefined,
+                                       _acc) ->
+    _acc;
+encode_vcard_sound_SOUND_PHONETIC_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_key_KEY({xmlel, _, _attrs, _els}) ->
+    {Cred, Type} = decode_vcard_key_KEY_els(_els, [],
+                                           undefined),
+    {vcard_key, Type, Cred}.
+
+decode_vcard_key_KEY_els([{xmlel, <<"CRED">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Cred, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_key_KEY_els(_els,
+                                  [decode_vcard_key_KEY_CRED(_el) | Cred],
+                                  Type);
+      _ -> decode_vcard_key_KEY_els(_els, Cred, Type)
+    end;
+decode_vcard_key_KEY_els([{xmlel, <<"TYPE">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Cred, Type) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_key_KEY_els(_els, Cred,
+                                  decode_vcard_type_TYPE(_el));
+      _ -> decode_vcard_key_KEY_els(_els, Cred, Type)
+    end;
+decode_vcard_key_KEY_els([_ | _els], Cred, Type) ->
+    decode_vcard_key_KEY_els(_els, Cred, Type);
+decode_vcard_key_KEY_els([], [Cred], Type) ->
+    {Cred, Type}.
+
+encode_vcard_key_KEY(undefined, _acc) -> _acc;
+encode_vcard_key_KEY({vcard_key, Type, Cred}, _acc) ->
+    _els = encode_vcard_type_TYPE(Type,
+                                 encode_vcard_key_KEY_CRED(Cred, [])),
+    _attrs = [],
+    [{xmlel, <<"KEY">>, _attrs, _els} | _acc].
+
+decode_vcard_key_KEY_CRED({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_key_KEY_CRED_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_key_KEY_CRED_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_vcard_key_KEY_CRED_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_vcard_key_KEY_CRED_els([_ | _els], Cdata) ->
+    decode_vcard_key_KEY_CRED_els(_els, Cdata);
+decode_vcard_key_KEY_CRED_els([], Cdata) ->
+    decode_vcard_key_KEY_CRED_cdata(Cdata).
+
+encode_vcard_key_KEY_CRED(Cdata, _acc) ->
+    _els = encode_vcard_key_KEY_CRED_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"CRED">>, _attrs, _els} | _acc].
+
+decode_vcard_key_KEY_CRED_cdata(<<>>) -> undefined;
+decode_vcard_key_KEY_CRED_cdata(_val) -> _val.
+
+encode_vcard_key_KEY_CRED_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_key_KEY_CRED_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard({xmlel, _, _attrs, _els}) ->
+    {Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+     Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+     Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+     Photo, Nickname, N, Fn, Version} =
+       decode_vcard_vCard_els(_els, undefined, undefined,
+                              undefined, undefined, undefined, undefined,
+                              undefined, undefined, undefined, undefined, [],
+                              undefined, undefined, undefined, undefined,
+                              undefined, undefined, undefined, undefined, [],
+                              [], [], [], undefined, undefined, undefined,
+                              undefined, undefined, undefined),
+    {vcard, Version, Fn, N, Nickname, Photo, Bday, Adr,
+     Label, Tel, Email, Jabberid, Mailer, Tz, Geo, Title,
+     Role, Logo, Org, Categories, Note, Prodid, Rev,
+     Sort_string, Sound, Uid, Url, Class, Key, Desc}.
+
+decode_vcard_vCard_els([{xmlel, <<"DESC">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els,
+                                decode_vcard_vCard_DESC(_el), Key, Class, Url,
+                                Uid, Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"KEY">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc,
+                                decode_vcard_key_KEY(_el), Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"CLASS">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key,
+                                decode_vcard_vCard_CLASS(_el), Url, Uid, Sound,
+                                Sort_string, Rev, Prodid, Note, Categories,
+                                Org, Logo, Role, Title, Geo, Tz, Mailer,
+                                Jabberid, Email, Tel, Label, Adr, Bday, Photo,
+                                Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"URL">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class,
+                                decode_vcard_vCard_URL(_el), Uid, Sound,
+                                Sort_string, Rev, Prodid, Note, Categories,
+                                Org, Logo, Role, Title, Geo, Tz, Mailer,
+                                Jabberid, Email, Tel, Label, Adr, Bday, Photo,
+                                Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"UID">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url,
+                                decode_vcard_vCard_UID(_el), Sound,
+                                Sort_string, Rev, Prodid, Note, Categories,
+                                Org, Logo, Role, Title, Geo, Tz, Mailer,
+                                Jabberid, Email, Tel, Label, Adr, Bday, Photo,
+                                Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"SOUND">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                decode_vcard_sound_SOUND(_el), Sort_string,
+                                Rev, Prodid, Note, Categories, Org, Logo, Role,
+                                Title, Geo, Tz, Mailer, Jabberid, Email, Tel,
+                                Label, Adr, Bday, Photo, Nickname, N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"SORT-STRING">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, 'decode_vcard_vCard_SORT-STRING'(_el),
+                                Rev, Prodid, Note, Categories, Org, Logo, Role,
+                                Title, Geo, Tz, Mailer, Jabberid, Email, Tel,
+                                Label, Adr, Bday, Photo, Nickname, N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"REV">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string,
+                                decode_vcard_vCard_REV(_el), Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"PRODID">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev,
+                                decode_vcard_vCard_PRODID(_el), Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"NOTE">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid,
+                                decode_vcard_vCard_NOTE(_el), Categories, Org,
+                                Logo, Role, Title, Geo, Tz, Mailer, Jabberid,
+                                Email, Tel, Label, Adr, Bday, Photo, Nickname,
+                                N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"CATEGORIES">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                decode_vcard_vCard_CATEGORIES(_el), Org, Logo,
+                                Role, Title, Geo, Tz, Mailer, Jabberid, Email,
+                                Tel, Label, Adr, Bday, Photo, Nickname, N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"ORG">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, decode_vcard_org_ORG(_el), Logo,
+                                Role, Title, Geo, Tz, Mailer, Jabberid, Email,
+                                Tel, Label, Adr, Bday, Photo, Nickname, N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"LOGO">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, decode_vcard_logo_LOGO(_el),
+                                Role, Title, Geo, Tz, Mailer, Jabberid, Email,
+                                Tel, Label, Adr, Bday, Photo, Nickname, N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"ROLE">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo,
+                                decode_vcard_vCard_ROLE(_el), Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"TITLE">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role,
+                                decode_vcard_vCard_TITLE(_el), Geo, Tz, Mailer,
+                                Jabberid, Email, Tel, Label, Adr, Bday, Photo,
+                                Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"GEO">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title,
+                                decode_vcard_geo_GEO(_el), Tz, Mailer,
+                                Jabberid, Email, Tel, Label, Adr, Bday, Photo,
+                                Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"TZ">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo,
+                                decode_vcard_vCard_TZ(_el), Mailer, Jabberid,
+                                Email, Tel, Label, Adr, Bday, Photo, Nickname,
+                                N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"MAILER">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                decode_vcard_vCard_MAILER(_el), Jabberid,
+                                Email, Tel, Label, Adr, Bday, Photo, Nickname,
+                                N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"JABBERID">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, decode_vcard_vCard_JABBERID(_el),
+                                Email, Tel, Label, Adr, Bday, Photo, Nickname,
+                                N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"EMAIL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid,
+                                [decode_vcard_email_EMAIL(_el) | Email], Tel,
+                                Label, Adr, Bday, Photo, Nickname, N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"TEL">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email,
+                                [decode_vcard_tel_TEL(_el) | Tel], Label, Adr,
+                                Bday, Photo, Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"LABEL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel,
+                                [decode_vcard_label_LABEL(_el) | Label], Adr,
+                                Bday, Photo, Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"ADR">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label,
+                                [decode_vcard_adr_ADR(_el) | Adr], Bday, Photo,
+                                Nickname, N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"BDAY">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr,
+                                decode_vcard_vCard_BDAY(_el), Photo, Nickname,
+                                N, Fn, Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"PHOTO">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                decode_vcard_photo_PHOTO(_el), Nickname, N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"NICKNAME">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, decode_vcard_vCard_NICKNAME(_el), N, Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"N">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, decode_vcard_name_N(_el), Fn,
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"FN">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, decode_vcard_vCard_FN(_el),
+                                Version);
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([{xmlel, <<"VERSION">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+                      Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+                      Tz, Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                      Photo, Nickname, N, Fn, Version) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn,
+                                decode_vcard_vCard_VERSION(_el));
+      _ ->
+         decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                                Sound, Sort_string, Rev, Prodid, Note,
+                                Categories, Org, Logo, Role, Title, Geo, Tz,
+                                Mailer, Jabberid, Email, Tel, Label, Adr, Bday,
+                                Photo, Nickname, N, Fn, Version)
+    end;
+decode_vcard_vCard_els([_ | _els], Desc, Key, Class,
+                      Url, Uid, Sound, Sort_string, Rev, Prodid, Note,
+                      Categories, Org, Logo, Role, Title, Geo, Tz, Mailer,
+                      Jabberid, Email, Tel, Label, Adr, Bday, Photo, Nickname,
+                      N, Fn, Version) ->
+    decode_vcard_vCard_els(_els, Desc, Key, Class, Url, Uid,
+                          Sound, Sort_string, Rev, Prodid, Note, Categories,
+                          Org, Logo, Role, Title, Geo, Tz, Mailer, Jabberid,
+                          Email, Tel, Label, Adr, Bday, Photo, Nickname, N, Fn,
+                          Version);
+decode_vcard_vCard_els([], Desc, Key, Class, Url, Uid,
+                      Sound, Sort_string, Rev, Prodid, Note, Categories, Org,
+                      Logo, Role, Title, Geo, Tz, Mailer, Jabberid, Email,
+                      Tel, Label, Adr, Bday, Photo, Nickname, N, Fn,
+                      Version) ->
+    {Desc, Key, Class, Url, Uid, Sound, Sort_string, Rev,
+     Prodid, Note, Categories, Org, Logo, Role, Title, Geo,
+     Tz, Mailer, Jabberid, lists:reverse(Email),
+     lists:reverse(Tel), lists:reverse(Label),
+     lists:reverse(Adr), Bday, Photo, Nickname, N, Fn,
+     Version}.
+
+encode_vcard_vCard(undefined, _acc) -> _acc;
+encode_vcard_vCard({vcard, Version, Fn, N, Nickname,
+                   Photo, Bday, Adr, Label, Tel, Email, Jabberid, Mailer,
+                   Tz, Geo, Title, Role, Logo, Org, Categories, Note,
+                   Prodid, Rev, Sort_string, Sound, Uid, Url, Class, Key,
+                   Desc},
+                  _acc) ->
+    _els = encode_vcard_vCard_VERSION(Version,
+                                     encode_vcard_vCard_FN(Fn,
+                                                           encode_vcard_name_N(N,
+                                                                               encode_vcard_vCard_NICKNAME(Nickname,
+                                                                                                           encode_vcard_photo_PHOTO(Photo,
+                                                                                                                                    encode_vcard_vCard_BDAY(Bday,
+                                                                                                                                                            encode_vcard_adr_ADR(Adr,
+                                                                                                                                                                                 encode_vcard_label_LABEL(Label,
+                                                                                                                                                                                                          encode_vcard_tel_TEL(Tel,
+                                                                                                                                                                                                                               encode_vcard_email_EMAIL(Email,
+                                                                                                                                                                                                                                                        encode_vcard_vCard_JABBERID(Jabberid,
+                                                                                                                                                                                                                                                                                    encode_vcard_vCard_MAILER(Mailer,
+                                                                                                                                                                                                                                                                                                              encode_vcard_vCard_TZ(Tz,
+                                                                                                                                                                                                                                                                                                                                    encode_vcard_geo_GEO(Geo,
+                                                                                                                                                                                                                                                                                                                                                         encode_vcard_vCard_TITLE(Title,
+                                                                                                                                                                                                                                                                                                                                                                                  encode_vcard_vCard_ROLE(Role,
+                                                                                                                                                                                                                                                                                                                                                                                                          encode_vcard_logo_LOGO(Logo,
+                                                                                                                                                                                                                                                                                                                                                                                                                                 encode_vcard_org_ORG(Org,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                      encode_vcard_vCard_CATEGORIES(Categories,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    encode_vcard_vCard_NOTE(Note,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            encode_vcard_vCard_PRODID(Prodid,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      encode_vcard_vCard_REV(Rev,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             'encode_vcard_vCard_SORT-STRING'(Sort_string,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              encode_vcard_sound_SOUND(Sound,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       encode_vcard_vCard_UID(Uid,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              encode_vcard_vCard_URL(Url,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     encode_vcard_vCard_CLASS(Class,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              encode_vcard_key_KEY(Key,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   encode_vcard_vCard_DESC(Desc,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           []))))))))))))))))))))))))))))),
+    _attrs = [{<<"xmlns">>, <<"vcard-temp">>}],
+    [{xmlel, <<"vCard">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_DESC({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_DESC_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_DESC_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_vcard_vCard_DESC_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_DESC_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_DESC_els(_els, Cdata);
+decode_vcard_vCard_DESC_els([], Cdata) ->
+    decode_vcard_vCard_DESC_cdata(Cdata).
+
+encode_vcard_vCard_DESC(undefined, _acc) -> _acc;
+encode_vcard_vCard_DESC(Cdata, _acc) ->
+    _els = encode_vcard_vCard_DESC_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"DESC">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_DESC_cdata(<<>>) -> undefined;
+decode_vcard_vCard_DESC_cdata(_val) -> _val.
+
+encode_vcard_vCard_DESC_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_DESC_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_CLASS({xmlel, _, _attrs, _els}) ->
+    Value = decode_vcard_vCard_CLASS_els(_els, undefined),
+    Value.
+
+decode_vcard_vCard_CLASS_els([{xmlel,
+                              <<"CONFIDENTIAL">>, _attrs, _} =
+                                 _el
+                             | _els],
+                            Value) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_CLASS_els(_els,
+                                      decode_vcard_vCard_CLASS_CONFIDENTIAL(_el));
+      _ -> decode_vcard_vCard_CLASS_els(_els, Value)
+    end;
+decode_vcard_vCard_CLASS_els([{xmlel, <<"PRIVATE">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Value) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_CLASS_els(_els,
+                                      decode_vcard_vCard_CLASS_PRIVATE(_el));
+      _ -> decode_vcard_vCard_CLASS_els(_els, Value)
+    end;
+decode_vcard_vCard_CLASS_els([{xmlel, <<"PUBLIC">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Value) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_CLASS_els(_els,
+                                      decode_vcard_vCard_CLASS_PUBLIC(_el));
+      _ -> decode_vcard_vCard_CLASS_els(_els, Value)
+    end;
+decode_vcard_vCard_CLASS_els([_ | _els], Value) ->
+    decode_vcard_vCard_CLASS_els(_els, Value);
+decode_vcard_vCard_CLASS_els([], Value) -> Value.
+
+'encode_vcard_vCard_CLASS_$value'(undefined, _acc) ->
+    _acc;
+'encode_vcard_vCard_CLASS_$value'(confidential = _r,
+                                 _acc) ->
+    encode_vcard_vCard_CLASS_CONFIDENTIAL(_r, _acc);
+'encode_vcard_vCard_CLASS_$value'(private = _r, _acc) ->
+    encode_vcard_vCard_CLASS_PRIVATE(_r, _acc);
+'encode_vcard_vCard_CLASS_$value'(public = _r, _acc) ->
+    encode_vcard_vCard_CLASS_PUBLIC(_r, _acc).
+
+encode_vcard_vCard_CLASS(undefined, _acc) -> _acc;
+encode_vcard_vCard_CLASS(Value, _acc) ->
+    _els = 'encode_vcard_vCard_CLASS_$value'(Value, []),
+    _attrs = [],
+    [{xmlel, <<"CLASS">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_CLASS_CONFIDENTIAL({xmlel, _, _attrs,
+                                      _els}) ->
+    confidential.
+
+encode_vcard_vCard_CLASS_CONFIDENTIAL(undefined,
+                                     _acc) ->
+    _acc;
+encode_vcard_vCard_CLASS_CONFIDENTIAL(confidential,
+                                     _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"CONFIDENTIAL">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_CLASS_PRIVATE({xmlel, _, _attrs,
+                                 _els}) ->
+    private.
+
+encode_vcard_vCard_CLASS_PRIVATE(undefined, _acc) ->
+    _acc;
+encode_vcard_vCard_CLASS_PRIVATE(private, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PRIVATE">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_CLASS_PUBLIC({xmlel, _, _attrs,
+                                _els}) ->
+    public.
+
+encode_vcard_vCard_CLASS_PUBLIC(undefined, _acc) ->
+    _acc;
+encode_vcard_vCard_CLASS_PUBLIC(public, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"PUBLIC">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_URL({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_URL_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_URL_els([{xmlcdata, _data} | _els],
+                          Cdata) ->
+    decode_vcard_vCard_URL_els(_els,
+                              <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_URL_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_URL_els(_els, Cdata);
+decode_vcard_vCard_URL_els([], Cdata) ->
+    decode_vcard_vCard_URL_cdata(Cdata).
+
+encode_vcard_vCard_URL(undefined, _acc) -> _acc;
+encode_vcard_vCard_URL(Cdata, _acc) ->
+    _els = encode_vcard_vCard_URL_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"URL">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_URL_cdata(<<>>) -> undefined;
+decode_vcard_vCard_URL_cdata(_val) -> _val.
+
+encode_vcard_vCard_URL_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_URL_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_UID({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_UID_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_UID_els([{xmlcdata, _data} | _els],
+                          Cdata) ->
+    decode_vcard_vCard_UID_els(_els,
+                              <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_UID_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_UID_els(_els, Cdata);
+decode_vcard_vCard_UID_els([], Cdata) ->
+    decode_vcard_vCard_UID_cdata(Cdata).
+
+encode_vcard_vCard_UID(undefined, _acc) -> _acc;
+encode_vcard_vCard_UID(Cdata, _acc) ->
+    _els = encode_vcard_vCard_UID_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"UID">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_UID_cdata(<<>>) -> undefined;
+decode_vcard_vCard_UID_cdata(_val) -> _val.
+
+encode_vcard_vCard_UID_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_UID_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+'decode_vcard_vCard_SORT-STRING'({xmlel, _, _attrs,
+                                 _els}) ->
+    Cdata = 'decode_vcard_vCard_SORT-STRING_els'(_els,
+                                                <<>>),
+    Cdata.
+
+'decode_vcard_vCard_SORT-STRING_els'([{xmlcdata, _data}
+                                     | _els],
+                                    Cdata) ->
+    'decode_vcard_vCard_SORT-STRING_els'(_els,
+                                        <<Cdata/binary, _data/binary>>);
+'decode_vcard_vCard_SORT-STRING_els'([_ | _els],
+                                    Cdata) ->
+    'decode_vcard_vCard_SORT-STRING_els'(_els, Cdata);
+'decode_vcard_vCard_SORT-STRING_els'([], Cdata) ->
+    'decode_vcard_vCard_SORT-STRING_cdata'(Cdata).
+
+'encode_vcard_vCard_SORT-STRING'(undefined, _acc) ->
+    _acc;
+'encode_vcard_vCard_SORT-STRING'(Cdata, _acc) ->
+    _els = 'encode_vcard_vCard_SORT-STRING_cdata'(Cdata,
+                                                 []),
+    _attrs = [],
+    [{xmlel, <<"SORT-STRING">>, _attrs, _els} | _acc].
+
+'decode_vcard_vCard_SORT-STRING_cdata'(<<>>) ->
+    undefined;
+'decode_vcard_vCard_SORT-STRING_cdata'(_val) -> _val.
+
+'encode_vcard_vCard_SORT-STRING_cdata'(undefined,
+                                      _acc) ->
+    _acc;
+'encode_vcard_vCard_SORT-STRING_cdata'(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_REV({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_REV_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_REV_els([{xmlcdata, _data} | _els],
+                          Cdata) ->
+    decode_vcard_vCard_REV_els(_els,
+                              <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_REV_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_REV_els(_els, Cdata);
+decode_vcard_vCard_REV_els([], Cdata) ->
+    decode_vcard_vCard_REV_cdata(Cdata).
+
+encode_vcard_vCard_REV(undefined, _acc) -> _acc;
+encode_vcard_vCard_REV(Cdata, _acc) ->
+    _els = encode_vcard_vCard_REV_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"REV">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_REV_cdata(<<>>) -> undefined;
+decode_vcard_vCard_REV_cdata(_val) -> _val.
+
+encode_vcard_vCard_REV_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_REV_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_PRODID({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_PRODID_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_vCard_PRODID_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_vcard_vCard_PRODID_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_PRODID_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_PRODID_els(_els, Cdata);
+decode_vcard_vCard_PRODID_els([], Cdata) ->
+    decode_vcard_vCard_PRODID_cdata(Cdata).
+
+encode_vcard_vCard_PRODID(undefined, _acc) -> _acc;
+encode_vcard_vCard_PRODID(Cdata, _acc) ->
+    _els = encode_vcard_vCard_PRODID_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"PRODID">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_PRODID_cdata(<<>>) -> undefined;
+decode_vcard_vCard_PRODID_cdata(_val) -> _val.
+
+encode_vcard_vCard_PRODID_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_vCard_PRODID_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_NOTE({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_NOTE_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_NOTE_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_vcard_vCard_NOTE_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_NOTE_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_NOTE_els(_els, Cdata);
+decode_vcard_vCard_NOTE_els([], Cdata) ->
+    decode_vcard_vCard_NOTE_cdata(Cdata).
+
+encode_vcard_vCard_NOTE(undefined, _acc) -> _acc;
+encode_vcard_vCard_NOTE(Cdata, _acc) ->
+    _els = encode_vcard_vCard_NOTE_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"NOTE">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_NOTE_cdata(<<>>) -> undefined;
+decode_vcard_vCard_NOTE_cdata(_val) -> _val.
+
+encode_vcard_vCard_NOTE_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_NOTE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_CATEGORIES({xmlel, _, _attrs,
+                              _els}) ->
+    Keywords = decode_vcard_vCard_CATEGORIES_els(_els, []),
+    Keywords.
+
+decode_vcard_vCard_CATEGORIES_els([{xmlel,
+                                   <<"KEYWORD">>, _attrs, _} =
+                                      _el
+                                  | _els],
+                                 Keywords) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_vcard_vCard_CATEGORIES_els(_els,
+                                           [decode_vcard_vCard_CATEGORIES_KEYWORD(_el)
+                                            | Keywords]);
+      _ -> decode_vcard_vCard_CATEGORIES_els(_els, Keywords)
+    end;
+decode_vcard_vCard_CATEGORIES_els([_ | _els],
+                                 Keywords) ->
+    decode_vcard_vCard_CATEGORIES_els(_els, Keywords);
+decode_vcard_vCard_CATEGORIES_els([], Keywords) ->
+    lists:reverse(Keywords).
+
+encode_vcard_vCard_CATEGORIES([], _acc) -> _acc;
+encode_vcard_vCard_CATEGORIES(Keywords, _acc) ->
+    _els = encode_vcard_vCard_CATEGORIES_KEYWORD(Keywords,
+                                                []),
+    _attrs = [],
+    [{xmlel, <<"CATEGORIES">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_CATEGORIES_KEYWORD({xmlel, _, _attrs,
+                                      _els}) ->
+    Cdata = decode_vcard_vCard_CATEGORIES_KEYWORD_els(_els,
+                                                     <<>>),
+    Cdata.
+
+decode_vcard_vCard_CATEGORIES_KEYWORD_els([{xmlcdata,
+                                           _data}
+                                          | _els],
+                                         Cdata) ->
+    decode_vcard_vCard_CATEGORIES_KEYWORD_els(_els,
+                                             <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_CATEGORIES_KEYWORD_els([_ | _els],
+                                         Cdata) ->
+    decode_vcard_vCard_CATEGORIES_KEYWORD_els(_els, Cdata);
+decode_vcard_vCard_CATEGORIES_KEYWORD_els([], Cdata) ->
+    decode_vcard_vCard_CATEGORIES_KEYWORD_cdata(Cdata).
+
+encode_vcard_vCard_CATEGORIES_KEYWORD([], _acc) -> _acc;
+encode_vcard_vCard_CATEGORIES_KEYWORD([Cdata | _tail],
+                                     _acc) ->
+    _els =
+       encode_vcard_vCard_CATEGORIES_KEYWORD_cdata(Cdata, []),
+    _attrs = [],
+    encode_vcard_vCard_CATEGORIES_KEYWORD(_tail,
+                                         [{xmlel, <<"KEYWORD">>, _attrs, _els}
+                                          | _acc]).
+
+decode_vcard_vCard_CATEGORIES_KEYWORD_cdata(<<>>) ->
+    undefined;
+decode_vcard_vCard_CATEGORIES_KEYWORD_cdata(_val) ->
+    _val.
+
+encode_vcard_vCard_CATEGORIES_KEYWORD_cdata(undefined,
+                                           _acc) ->
+    _acc;
+encode_vcard_vCard_CATEGORIES_KEYWORD_cdata(_val,
+                                           _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_ROLE({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_ROLE_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_ROLE_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_vcard_vCard_ROLE_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_ROLE_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_ROLE_els(_els, Cdata);
+decode_vcard_vCard_ROLE_els([], Cdata) ->
+    decode_vcard_vCard_ROLE_cdata(Cdata).
+
+encode_vcard_vCard_ROLE(undefined, _acc) -> _acc;
+encode_vcard_vCard_ROLE(Cdata, _acc) ->
+    _els = encode_vcard_vCard_ROLE_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"ROLE">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_ROLE_cdata(<<>>) -> undefined;
+decode_vcard_vCard_ROLE_cdata(_val) -> _val.
+
+encode_vcard_vCard_ROLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_ROLE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_TITLE({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_TITLE_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_TITLE_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_vcard_vCard_TITLE_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_TITLE_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_TITLE_els(_els, Cdata);
+decode_vcard_vCard_TITLE_els([], Cdata) ->
+    decode_vcard_vCard_TITLE_cdata(Cdata).
+
+encode_vcard_vCard_TITLE(undefined, _acc) -> _acc;
+encode_vcard_vCard_TITLE(Cdata, _acc) ->
+    _els = encode_vcard_vCard_TITLE_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"TITLE">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_TITLE_cdata(<<>>) -> undefined;
+decode_vcard_vCard_TITLE_cdata(_val) -> _val.
+
+encode_vcard_vCard_TITLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_TITLE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_TZ({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_TZ_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_TZ_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_vcard_vCard_TZ_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_TZ_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_TZ_els(_els, Cdata);
+decode_vcard_vCard_TZ_els([], Cdata) ->
+    decode_vcard_vCard_TZ_cdata(Cdata).
+
+encode_vcard_vCard_TZ(undefined, _acc) -> _acc;
+encode_vcard_vCard_TZ(Cdata, _acc) ->
+    _els = encode_vcard_vCard_TZ_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"TZ">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_TZ_cdata(<<>>) -> undefined;
+decode_vcard_vCard_TZ_cdata(_val) -> _val.
+
+encode_vcard_vCard_TZ_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_TZ_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_MAILER({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_MAILER_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_vCard_MAILER_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_vcard_vCard_MAILER_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_MAILER_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_MAILER_els(_els, Cdata);
+decode_vcard_vCard_MAILER_els([], Cdata) ->
+    decode_vcard_vCard_MAILER_cdata(Cdata).
+
+encode_vcard_vCard_MAILER(undefined, _acc) -> _acc;
+encode_vcard_vCard_MAILER(Cdata, _acc) ->
+    _els = encode_vcard_vCard_MAILER_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"MAILER">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_MAILER_cdata(<<>>) -> undefined;
+decode_vcard_vCard_MAILER_cdata(_val) -> _val.
+
+encode_vcard_vCard_MAILER_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_vCard_MAILER_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_JABBERID({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_JABBERID_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_vCard_JABBERID_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_vcard_vCard_JABBERID_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_JABBERID_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_JABBERID_els(_els, Cdata);
+decode_vcard_vCard_JABBERID_els([], Cdata) ->
+    decode_vcard_vCard_JABBERID_cdata(Cdata).
+
+encode_vcard_vCard_JABBERID(undefined, _acc) -> _acc;
+encode_vcard_vCard_JABBERID(Cdata, _acc) ->
+    _els = encode_vcard_vCard_JABBERID_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"JABBERID">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_JABBERID_cdata(<<>>) -> undefined;
+decode_vcard_vCard_JABBERID_cdata(_val) -> _val.
+
+encode_vcard_vCard_JABBERID_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_vCard_JABBERID_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_BDAY({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_BDAY_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_BDAY_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_vcard_vCard_BDAY_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_BDAY_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_BDAY_els(_els, Cdata);
+decode_vcard_vCard_BDAY_els([], Cdata) ->
+    decode_vcard_vCard_BDAY_cdata(Cdata).
+
+encode_vcard_vCard_BDAY(undefined, _acc) -> _acc;
+encode_vcard_vCard_BDAY(Cdata, _acc) ->
+    _els = encode_vcard_vCard_BDAY_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"BDAY">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_BDAY_cdata(<<>>) -> undefined;
+decode_vcard_vCard_BDAY_cdata(_val) -> _val.
+
+encode_vcard_vCard_BDAY_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_BDAY_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_NICKNAME({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_NICKNAME_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_vCard_NICKNAME_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_vcard_vCard_NICKNAME_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_NICKNAME_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_NICKNAME_els(_els, Cdata);
+decode_vcard_vCard_NICKNAME_els([], Cdata) ->
+    decode_vcard_vCard_NICKNAME_cdata(Cdata).
+
+encode_vcard_vCard_NICKNAME(undefined, _acc) -> _acc;
+encode_vcard_vCard_NICKNAME(Cdata, _acc) ->
+    _els = encode_vcard_vCard_NICKNAME_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"NICKNAME">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_NICKNAME_cdata(<<>>) -> undefined;
+decode_vcard_vCard_NICKNAME_cdata(_val) -> _val.
+
+encode_vcard_vCard_NICKNAME_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_vCard_NICKNAME_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_FN({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_FN_els(_els, <<>>), Cdata.
+
+decode_vcard_vCard_FN_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_vcard_vCard_FN_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_FN_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_FN_els(_els, Cdata);
+decode_vcard_vCard_FN_els([], Cdata) ->
+    decode_vcard_vCard_FN_cdata(Cdata).
+
+encode_vcard_vCard_FN(undefined, _acc) -> _acc;
+encode_vcard_vCard_FN(Cdata, _acc) ->
+    _els = encode_vcard_vCard_FN_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"FN">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_FN_cdata(<<>>) -> undefined;
+decode_vcard_vCard_FN_cdata(_val) -> _val.
+
+encode_vcard_vCard_FN_cdata(undefined, _acc) -> _acc;
+encode_vcard_vCard_FN_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_vCard_VERSION({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_vcard_vCard_VERSION_els(_els, <<>>),
+    Cdata.
+
+decode_vcard_vCard_VERSION_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_vcard_vCard_VERSION_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_vcard_vCard_VERSION_els([_ | _els], Cdata) ->
+    decode_vcard_vCard_VERSION_els(_els, Cdata);
+decode_vcard_vCard_VERSION_els([], Cdata) ->
+    decode_vcard_vCard_VERSION_cdata(Cdata).
+
+encode_vcard_vCard_VERSION(undefined, _acc) -> _acc;
+encode_vcard_vCard_VERSION(Cdata, _acc) ->
+    _els = encode_vcard_vCard_VERSION_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"VERSION">>, _attrs, _els} | _acc].
+
+decode_vcard_vCard_VERSION_cdata(<<>>) -> undefined;
+decode_vcard_vCard_VERSION_cdata(_val) -> _val.
+
+encode_vcard_vCard_VERSION_cdata(undefined, _acc) ->
+    _acc;
+encode_vcard_vCard_VERSION_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_xfield_field({xmlel, _, _attrs, _els}) ->
+    {Var, Type, Label} = decode_xfield_field_attrs(_attrs,
+                                                  undefined, undefined,
+                                                  undefined),
+    {Options, Values, Desc, Required} =
+       decode_xfield_field_els(_els, [], [], undefined, false),
+    {xfield, Label, Type, Var, Required, Desc, Values,
+     Options}.
+
+decode_xfield_field_els([{xmlel, <<"option">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Options, Values, Desc, Required) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xfield_field_els(_els,
+                                 [decode_xfield_field_option(_el) | Options],
+                                 Values, Desc, Required);
+      _ ->
+         decode_xfield_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xfield_field_els([{xmlel, <<"value">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Options, Values, Desc, Required) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xfield_field_els(_els, Options,
+                                 [decode_xfield_field_value(_el) | Values],
+                                 Desc, Required);
+      _ ->
+         decode_xfield_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xfield_field_els([{xmlel, <<"desc">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Options, Values, Desc, Required) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xfield_field_els(_els, Options, Values,
+                                 decode_xfield_field_desc(_el), Required);
+      _ ->
+         decode_xfield_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xfield_field_els([{xmlel, <<"required">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Options, Values, Desc, Required) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xfield_field_els(_els, Options, Values, Desc,
+                                 decode_xfield_field_required(_el));
+      _ ->
+         decode_xfield_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xfield_field_els([_ | _els], Options, Values,
+                       Desc, Required) ->
+    decode_xfield_field_els(_els, Options, Values, Desc,
+                           Required);
+decode_xfield_field_els([], Options, Values, Desc,
+                       Required) ->
+    {lists:reverse(Options), lists:reverse(Values), Desc,
+     Required}.
+
+decode_xfield_field_attrs([{<<"var">>, _val} | _attrs],
+                         _Var, Type, Label) ->
+    decode_xfield_field_attrs(_attrs, _val, Type, Label);
+decode_xfield_field_attrs([{<<"type">>, _val} | _attrs],
+                         Var, _Type, Label) ->
+    decode_xfield_field_attrs(_attrs, Var, _val, Label);
+decode_xfield_field_attrs([{<<"label">>, _val}
+                          | _attrs],
+                         Var, Type, _Label) ->
+    decode_xfield_field_attrs(_attrs, Var, Type, _val);
+decode_xfield_field_attrs([_ | _attrs], Var, Type,
+                         Label) ->
+    decode_xfield_field_attrs(_attrs, Var, Type, Label);
+decode_xfield_field_attrs([], Var, Type, Label) ->
+    {decode_xfield_field_var(Var),
+     decode_xfield_field_type(Type),
+     decode_xfield_field_label(Label)}.
+
+encode_xfield_field([], _acc) -> _acc;
+encode_xfield_field([{xfield, Label, Type, Var,
+                     Required, Desc, Values, Options}
+                    | _tail],
+                   _acc) ->
+    _els = encode_xfield_field_required(Required,
+                                       encode_xfield_field_desc(Desc,
+                                                                encode_xfield_field_value(Values,
+                                                                                          encode_xfield_field_option(Options,
+                                                                                                                     [])))),
+    _attrs = encode_xfield_field_label(Label,
+                                      encode_xfield_field_type(Type,
+                                                               encode_xfield_field_var(Var,
+                                                                                       []))),
+    encode_xfield_field(_tail,
+                       [{xmlel, <<"field">>, _attrs, _els} | _acc]).
+
+decode_xfield_field_label(undefined) -> undefined;
+decode_xfield_field_label(_val) -> _val.
+
+encode_xfield_field_label(undefined, _acc) -> _acc;
+encode_xfield_field_label(_val, _acc) ->
+    [{<<"label">>, _val} | _acc].
+
+decode_xfield_field_type(undefined) -> undefined;
+decode_xfield_field_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [boolean, fixed, hidden, 'jid-multi',
+                                'jid-single', 'list-multi', 'list-single',
+                                'text-multi', 'text-private', 'text-single'])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"field">>,
+                       <<>>});
+      _res -> _res
+    end.
+
+encode_xfield_field_type(undefined, _acc) -> _acc;
+encode_xfield_field_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_xfield_field_var(undefined) -> undefined;
+decode_xfield_field_var(_val) -> _val.
+
+encode_xfield_field_var(undefined, _acc) -> _acc;
+encode_xfield_field_var(_val, _acc) ->
+    [{<<"var">>, _val} | _acc].
+
+decode_xfield_field_option({xmlel, _, _attrs, _els}) ->
+    Value = decode_xfield_field_option_els(_els, []), Value.
+
+decode_xfield_field_option_els([{xmlel, <<"value">>,
+                                _attrs, _} =
+                                   _el
+                               | _els],
+                              Value) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xfield_field_option_els(_els,
+                                        [decode_xfield_field_option_value(_el)
+                                         | Value]);
+      _ -> decode_xfield_field_option_els(_els, Value)
+    end;
+decode_xfield_field_option_els([_ | _els], Value) ->
+    decode_xfield_field_option_els(_els, Value);
+decode_xfield_field_option_els([], [Value]) -> Value.
+
+encode_xfield_field_option([], _acc) -> _acc;
+encode_xfield_field_option([Value | _tail], _acc) ->
+    _els = encode_xfield_field_option_value(Value, []),
+    _attrs = [],
+    encode_xfield_field_option(_tail,
+                              [{xmlel, <<"option">>, _attrs, _els} | _acc]).
+
+decode_xfield_field_option_value({xmlel, _, _attrs,
+                                 _els}) ->
+    Cdata = decode_xfield_field_option_value_els(_els,
+                                                <<>>),
+    Cdata.
+
+decode_xfield_field_option_value_els([{xmlcdata, _data}
+                                     | _els],
+                                    Cdata) ->
+    decode_xfield_field_option_value_els(_els,
+                                        <<Cdata/binary, _data/binary>>);
+decode_xfield_field_option_value_els([_ | _els],
+                                    Cdata) ->
+    decode_xfield_field_option_value_els(_els, Cdata);
+decode_xfield_field_option_value_els([], Cdata) ->
+    decode_xfield_field_option_value_cdata(Cdata).
+
+encode_xfield_field_option_value(Cdata, _acc) ->
+    _els = encode_xfield_field_option_value_cdata(Cdata,
+                                                 []),
+    _attrs = [],
+    [{xmlel, <<"value">>, _attrs, _els} | _acc].
+
+decode_xfield_field_option_value_cdata(<<>>) ->
+    undefined;
+decode_xfield_field_option_value_cdata(_val) -> _val.
+
+encode_xfield_field_option_value_cdata(undefined,
+                                      _acc) ->
+    _acc;
+encode_xfield_field_option_value_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_xfield_field_value({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_xfield_field_value_els(_els, <<>>),
+    Cdata.
+
+decode_xfield_field_value_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_xfield_field_value_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_xfield_field_value_els([_ | _els], Cdata) ->
+    decode_xfield_field_value_els(_els, Cdata);
+decode_xfield_field_value_els([], Cdata) ->
+    decode_xfield_field_value_cdata(Cdata).
+
+encode_xfield_field_value([], _acc) -> _acc;
+encode_xfield_field_value([Cdata | _tail], _acc) ->
+    _els = encode_xfield_field_value_cdata(Cdata, []),
+    _attrs = [],
+    encode_xfield_field_value(_tail,
+                             [{xmlel, <<"value">>, _attrs, _els} | _acc]).
+
+decode_xfield_field_value_cdata(<<>>) -> undefined;
+decode_xfield_field_value_cdata(_val) -> _val.
+
+encode_xfield_field_value_cdata(undefined, _acc) ->
+    _acc;
+encode_xfield_field_value_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_xfield_field_desc({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_xfield_field_desc_els(_els, <<>>), Cdata.
+
+decode_xfield_field_desc_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_xfield_field_desc_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_xfield_field_desc_els([_ | _els], Cdata) ->
+    decode_xfield_field_desc_els(_els, Cdata);
+decode_xfield_field_desc_els([], Cdata) ->
+    decode_xfield_field_desc_cdata(Cdata).
+
+encode_xfield_field_desc(undefined, _acc) -> _acc;
+encode_xfield_field_desc(Cdata, _acc) ->
+    _els = encode_xfield_field_desc_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"desc">>, _attrs, _els} | _acc].
+
+decode_xfield_field_desc_cdata(<<>>) -> undefined;
+decode_xfield_field_desc_cdata(_val) -> _val.
+
+encode_xfield_field_desc_cdata(undefined, _acc) -> _acc;
+encode_xfield_field_desc_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_xfield_field_required({xmlel, _, _attrs,
+                             _els}) ->
+    true.
+
+encode_xfield_field_required(false, _acc) -> _acc;
+encode_xfield_field_required(true, _acc) ->
+    _els = [],
+    _attrs = [],
+    [{xmlel, <<"required">>, _attrs, _els} | _acc].
+
+decode_xdata_x({xmlel, _, _attrs, _els}) ->
+    Type = decode_xdata_x_attrs(_attrs, undefined),
+    {Fields, Items, Reported, Title, Instructions} =
+       decode_xdata_x_els(_els, [], [], undefined, undefined,
+                          []),
+    {xdata, Type, Instructions, Title, Reported, Items,
+     Fields}.
+
+decode_xdata_x_els([{xmlel, <<"field">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Fields, Items, Reported, Title, Instructions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xdata_x_els(_els,
+                            [decode_xfield_field(_el) | Fields], Items,
+                            Reported, Title, Instructions);
+      _ ->
+         decode_xdata_x_els(_els, Fields, Items, Reported, Title,
+                            Instructions)
+    end;
+decode_xdata_x_els([{xmlel, <<"item">>, _attrs, _} = _el
+                   | _els],
+                  Fields, Items, Reported, Title, Instructions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xdata_x_els(_els, Fields,
+                            [decode_xdata_x_item(_el) | Items], Reported,
+                            Title, Instructions);
+      _ ->
+         decode_xdata_x_els(_els, Fields, Items, Reported, Title,
+                            Instructions)
+    end;
+decode_xdata_x_els([{xmlel, <<"reported">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Fields, Items, Reported, Title, Instructions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xdata_x_els(_els, Fields, Items,
+                            decode_xdata_x_reported(_el), Title, Instructions);
+      _ ->
+         decode_xdata_x_els(_els, Fields, Items, Reported, Title,
+                            Instructions)
+    end;
+decode_xdata_x_els([{xmlel, <<"title">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Fields, Items, Reported, Title, Instructions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xdata_x_els(_els, Fields, Items, Reported,
+                            decode_xdata_x_title(_el), Instructions);
+      _ ->
+         decode_xdata_x_els(_els, Fields, Items, Reported, Title,
+                            Instructions)
+    end;
+decode_xdata_x_els([{xmlel, <<"instructions">>, _attrs,
+                    _} =
+                       _el
+                   | _els],
+                  Fields, Items, Reported, Title, Instructions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xdata_x_els(_els, Fields, Items, Reported, Title,
+                            [decode_xdata_x_instructions(_el) | Instructions]);
+      _ ->
+         decode_xdata_x_els(_els, Fields, Items, Reported, Title,
+                            Instructions)
+    end;
+decode_xdata_x_els([_ | _els], Fields, Items, Reported,
+                  Title, Instructions) ->
+    decode_xdata_x_els(_els, Fields, Items, Reported, Title,
+                      Instructions);
+decode_xdata_x_els([], Fields, Items, Reported, Title,
+                  Instructions) ->
+    {lists:reverse(Fields), lists:reverse(Items), Reported,
+     Title, lists:reverse(Instructions)}.
+
+decode_xdata_x_attrs([{<<"type">>, _val} | _attrs],
+                    _Type) ->
+    decode_xdata_x_attrs(_attrs, _val);
+decode_xdata_x_attrs([_ | _attrs], Type) ->
+    decode_xdata_x_attrs(_attrs, Type);
+decode_xdata_x_attrs([], Type) ->
+    decode_xdata_x_type(Type).
+
+encode_xdata_x([], _acc) -> _acc;
+encode_xdata_x([{xdata, Type, Instructions, Title,
+                Reported, Items, Fields}
+               | _tail],
+              _acc) ->
+    _els = encode_xdata_x_instructions(Instructions,
+                                      encode_xdata_x_title(Title,
+                                                           encode_xdata_x_reported(Reported,
+                                                                                   encode_xdata_x_item(Items,
+                                                                                                       encode_xfield_field(Fields,
+                                                                                                                           []))))),
+    _attrs = encode_xdata_x_type(Type,
+                                [{<<"xmlns">>, <<"jabber:x:data">>}]),
+    encode_xdata_x(_tail,
+                  [{xmlel, <<"x">>, _attrs, _els} | _acc]).
+
+decode_xdata_x_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"x">>,
+                 <<"jabber:x:data">>});
+decode_xdata_x_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [cancel, form, result, submit])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"x">>,
+                       <<"jabber:x:data">>});
+      _res -> _res
+    end.
+
+encode_xdata_x_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_xdata_x_item({xmlel, _, _attrs, _els}) ->
+    Fields = decode_xdata_x_item_els(_els, []), Fields.
+
+decode_xdata_x_item_els([{xmlel, <<"field">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Fields) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xdata_x_item_els(_els,
+                                 [decode_xfield_field(_el) | Fields]);
+      _ -> decode_xdata_x_item_els(_els, Fields)
+    end;
+decode_xdata_x_item_els([_ | _els], Fields) ->
+    decode_xdata_x_item_els(_els, Fields);
+decode_xdata_x_item_els([], Fields) ->
+    lists:reverse(Fields).
+
+encode_xdata_x_item([], _acc) -> _acc;
+encode_xdata_x_item([Fields | _tail], _acc) ->
+    _els = encode_xfield_field(Fields, []),
+    _attrs = [],
+    encode_xdata_x_item(_tail,
+                       [{xmlel, <<"item">>, _attrs, _els} | _acc]).
+
+decode_xdata_x_reported({xmlel, _, _attrs, _els}) ->
+    Fields = decode_xdata_x_reported_els(_els, []), Fields.
+
+decode_xdata_x_reported_els([{xmlel, <<"field">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Fields) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_xdata_x_reported_els(_els,
+                                     [decode_xfield_field(_el) | Fields]);
+      _ -> decode_xdata_x_reported_els(_els, Fields)
+    end;
+decode_xdata_x_reported_els([_ | _els], Fields) ->
+    decode_xdata_x_reported_els(_els, Fields);
+decode_xdata_x_reported_els([], Fields) ->
+    lists:reverse(Fields).
+
+encode_xdata_x_reported(undefined, _acc) -> _acc;
+encode_xdata_x_reported(Fields, _acc) ->
+    _els = encode_xfield_field(Fields, []),
+    _attrs = [],
+    [{xmlel, <<"reported">>, _attrs, _els} | _acc].
+
+decode_xdata_x_title({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_xdata_x_title_els(_els, <<>>), Cdata.
+
+decode_xdata_x_title_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_xdata_x_title_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_xdata_x_title_els([_ | _els], Cdata) ->
+    decode_xdata_x_title_els(_els, Cdata);
+decode_xdata_x_title_els([], Cdata) ->
+    decode_xdata_x_title_cdata(Cdata).
+
+encode_xdata_x_title(undefined, _acc) -> _acc;
+encode_xdata_x_title(Cdata, _acc) ->
+    _els = encode_xdata_x_title_cdata(Cdata, []),
+    _attrs = [],
+    [{xmlel, <<"title">>, _attrs, _els} | _acc].
+
+decode_xdata_x_title_cdata(<<>>) -> undefined;
+decode_xdata_x_title_cdata(_val) -> _val.
+
+encode_xdata_x_title_cdata(undefined, _acc) -> _acc;
+encode_xdata_x_title_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_xdata_x_instructions({xmlel, _, _attrs, _els}) ->
+    Cdata = decode_xdata_x_instructions_els(_els, <<>>),
+    Cdata.
+
+decode_xdata_x_instructions_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_xdata_x_instructions_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_xdata_x_instructions_els([_ | _els], Cdata) ->
+    decode_xdata_x_instructions_els(_els, Cdata);
+decode_xdata_x_instructions_els([], Cdata) ->
+    decode_xdata_x_instructions_cdata(Cdata).
+
+encode_xdata_x_instructions([], _acc) -> _acc;
+encode_xdata_x_instructions([Cdata | _tail], _acc) ->
+    _els = encode_xdata_x_instructions_cdata(Cdata, []),
+    _attrs = [],
+    encode_xdata_x_instructions(_tail,
+                               [{xmlel, <<"instructions">>, _attrs, _els}
+                                | _acc]).
+
+decode_xdata_x_instructions_cdata(<<>>) -> undefined;
+decode_xdata_x_instructions_cdata(_val) -> _val.
+
+encode_xdata_x_instructions_cdata(undefined, _acc) ->
+    _acc;
+encode_xdata_x_instructions_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_pubsub_subscription_subscription({xmlel, _,
+                                        _attrs, _els}) ->
+    {Type, Subid, Node, Jid} =
+       decode_pubsub_subscription_subscription_attrs(_attrs,
+                                                     undefined, undefined,
+                                                     undefined, undefined),
+    {pubsub_subscription, Jid, Node, Subid, Type}.
+
+decode_pubsub_subscription_subscription_attrs([{<<"subscription">>,
+                                               _val}
+                                              | _attrs],
+                                             _Type, Subid, Node, Jid) ->
+    decode_pubsub_subscription_subscription_attrs(_attrs,
+                                                 _val, Subid, Node, Jid);
+decode_pubsub_subscription_subscription_attrs([{<<"subid">>,
+                                               _val}
+                                              | _attrs],
+                                             Type, _Subid, Node, Jid) ->
+    decode_pubsub_subscription_subscription_attrs(_attrs,
+                                                 Type, _val, Node, Jid);
+decode_pubsub_subscription_subscription_attrs([{<<"node">>,
+                                               _val}
+                                              | _attrs],
+                                             Type, Subid, _Node, Jid) ->
+    decode_pubsub_subscription_subscription_attrs(_attrs,
+                                                 Type, Subid, _val, Jid);
+decode_pubsub_subscription_subscription_attrs([{<<"jid">>,
+                                               _val}
+                                              | _attrs],
+                                             Type, Subid, Node, _Jid) ->
+    decode_pubsub_subscription_subscription_attrs(_attrs,
+                                                 Type, Subid, Node, _val);
+decode_pubsub_subscription_subscription_attrs([_
+                                              | _attrs],
+                                             Type, Subid, Node, Jid) ->
+    decode_pubsub_subscription_subscription_attrs(_attrs,
+                                                 Type, Subid, Node, Jid);
+decode_pubsub_subscription_subscription_attrs([], Type,
+                                             Subid, Node, Jid) ->
+    {decode_pubsub_subscription_subscription_subscription(Type),
+     decode_pubsub_subscription_subscription_subid(Subid),
+     decode_pubsub_subscription_subscription_node(Node),
+     decode_pubsub_subscription_subscription_jid(Jid)}.
+
+encode_pubsub_subscription_subscription([], _acc) ->
+    _acc;
+encode_pubsub_subscription_subscription([{pubsub_subscription,
+                                         Jid, Node, Subid, Type}
+                                        | _tail],
+                                       _acc) ->
+    _els = [],
+    _attrs =
+       encode_pubsub_subscription_subscription_jid(Jid,
+                                                   encode_pubsub_subscription_subscription_node(Node,
+                                                                                                encode_pubsub_subscription_subscription_subid(Subid,
+                                                                                                                                              encode_pubsub_subscription_subscription_subscription(Type,
+                                                                                                                                                                                                   [])))),
+    encode_pubsub_subscription_subscription(_tail,
+                                           [{xmlel, <<"subscription">>, _attrs,
+                                             _els}
+                                            | _acc]).
+
+decode_pubsub_subscription_subscription_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>,
+                 <<"subscription">>, <<>>});
+decode_pubsub_subscription_subscription_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>,
+                       <<"subscription">>, <<>>});
+      _res -> _res
+    end.
+
+encode_pubsub_subscription_subscription_jid(_val,
+                                           _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
+
+decode_pubsub_subscription_subscription_node(undefined) ->
+    undefined;
+decode_pubsub_subscription_subscription_node(_val) ->
+    _val.
+
+encode_pubsub_subscription_subscription_node(undefined,
+                                            _acc) ->
+    _acc;
+encode_pubsub_subscription_subscription_node(_val,
+                                            _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_pubsub_subscription_subscription_subid(undefined) ->
+    undefined;
+decode_pubsub_subscription_subscription_subid(_val) ->
+    _val.
+
+encode_pubsub_subscription_subscription_subid(undefined,
+                                             _acc) ->
+    _acc;
+encode_pubsub_subscription_subscription_subid(_val,
+                                             _acc) ->
+    [{<<"subid">>, _val} | _acc].
+
+decode_pubsub_subscription_subscription_subscription(undefined) ->
+    undefined;
+decode_pubsub_subscription_subscription_subscription(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [none, pending, subscribed, unconfigured])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"subscription">>,
+                       <<"subscription">>, <<>>});
+      _res -> _res
+    end.
+
+encode_pubsub_subscription_subscription_subscription(undefined,
+                                                    _acc) ->
+    _acc;
+encode_pubsub_subscription_subscription_subscription(_val,
+                                                    _acc) ->
+    [{<<"subscription">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_pubsub_affiliation_affiliation({xmlel, _, _attrs,
+                                      _els}) ->
+    {Type, Node} =
+       decode_pubsub_affiliation_affiliation_attrs(_attrs,
+                                                   undefined, undefined),
+    {pubsub_affiliation, Node, Type}.
+
+decode_pubsub_affiliation_affiliation_attrs([{<<"affiliation">>,
+                                             _val}
+                                            | _attrs],
+                                           _Type, Node) ->
+    decode_pubsub_affiliation_affiliation_attrs(_attrs,
+                                               _val, Node);
+decode_pubsub_affiliation_affiliation_attrs([{<<"node">>,
+                                             _val}
+                                            | _attrs],
+                                           Type, _Node) ->
+    decode_pubsub_affiliation_affiliation_attrs(_attrs,
+                                               Type, _val);
+decode_pubsub_affiliation_affiliation_attrs([_
+                                            | _attrs],
+                                           Type, Node) ->
+    decode_pubsub_affiliation_affiliation_attrs(_attrs,
+                                               Type, Node);
+decode_pubsub_affiliation_affiliation_attrs([], Type,
+                                           Node) ->
+    {decode_pubsub_affiliation_affiliation_affiliation(Type),
+     decode_pubsub_affiliation_affiliation_node(Node)}.
+
+encode_pubsub_affiliation_affiliation([], _acc) -> _acc;
+encode_pubsub_affiliation_affiliation([{pubsub_affiliation,
+                                       Node, Type}
+                                      | _tail],
+                                     _acc) ->
+    _els = [],
+    _attrs =
+       encode_pubsub_affiliation_affiliation_node(Node,
+                                                  encode_pubsub_affiliation_affiliation_affiliation(Type,
+                                                                                                    [])),
+    encode_pubsub_affiliation_affiliation(_tail,
+                                         [{xmlel, <<"affiliation">>, _attrs,
+                                           _els}
+                                          | _acc]).
+
+decode_pubsub_affiliation_affiliation_node(undefined) ->
+    erlang:error({missing_attr, <<"node">>,
+                 <<"affiliation">>, <<>>});
+decode_pubsub_affiliation_affiliation_node(_val) ->
+    _val.
+
+encode_pubsub_affiliation_affiliation_node(_val,
+                                          _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_pubsub_affiliation_affiliation_affiliation(undefined) ->
+    erlang:error({missing_attr, <<"affiliation">>,
+                 <<"affiliation">>, <<>>});
+decode_pubsub_affiliation_affiliation_affiliation(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [member, none, outcast, owner, publisher,
+                                'publish-only'])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"affiliation">>,
+                       <<"affiliation">>, <<>>});
+      _res -> _res
+    end.
+
+encode_pubsub_affiliation_affiliation_affiliation(_val,
+                                                 _acc) ->
+    [{<<"affiliation">>, xml_gen:enc_enum(_val)} | _acc].
+
+decode_pubsub_item_item({xmlel, _, _attrs, _els}) ->
+    Id = decode_pubsub_item_item_attrs(_attrs, undefined),
+    __Els = decode_pubsub_item_item_els(_els, []),
+    {pubsub_item, Id, __Els}.
+
+decode_pubsub_item_item_els([{xmlel, _, _, _} = _el
+                            | _els],
+                           __Els) ->
+    decode_pubsub_item_item_els(_els,
+                               [decode(_el) | __Els]);
+decode_pubsub_item_item_els([_ | _els], __Els) ->
+    decode_pubsub_item_item_els(_els, __Els);
+decode_pubsub_item_item_els([], __Els) ->
+    lists:reverse(__Els).
+
+decode_pubsub_item_item_attrs([{<<"id">>, _val}
+                              | _attrs],
+                             _Id) ->
+    decode_pubsub_item_item_attrs(_attrs, _val);
+decode_pubsub_item_item_attrs([_ | _attrs], Id) ->
+    decode_pubsub_item_item_attrs(_attrs, Id);
+decode_pubsub_item_item_attrs([], Id) ->
+    decode_pubsub_item_item_id(Id).
+
+encode_pubsub_item_item([], _acc) -> _acc;
+encode_pubsub_item_item([{pubsub_item, Id, __Els}
+                        | _tail],
+                       _acc) ->
+    _els = [encode(_subel) || _subel <- __Els] ++ [],
+    _attrs = encode_pubsub_item_item_id(Id, []),
+    encode_pubsub_item_item(_tail,
+                           [{xmlel, <<"item">>, _attrs, _els} | _acc]).
+
+decode_pubsub_item_item_id(undefined) -> undefined;
+decode_pubsub_item_item_id(_val) -> _val.
+
+encode_pubsub_item_item_id(undefined, _acc) -> _acc;
+encode_pubsub_item_item_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
+
+decode_pubsub_items_items({xmlel, _, _attrs, _els}) ->
+    {Subid, Max_items, Node} =
+       decode_pubsub_items_items_attrs(_attrs, undefined,
+                                       undefined, undefined),
+    Item = decode_pubsub_items_items_els(_els, []),
+    {pubsub_items, Node, Max_items, Subid, Item}.
+
+decode_pubsub_items_items_els([{xmlel, <<"item">>,
+                               _attrs, _} =
+                                  _el
+                              | _els],
+                             Item) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_items_items_els(_els,
+                                       [decode_pubsub_item_item(_el) | Item]);
+      _ -> decode_pubsub_items_items_els(_els, Item)
+    end;
+decode_pubsub_items_items_els([_ | _els], Item) ->
+    decode_pubsub_items_items_els(_els, Item);
+decode_pubsub_items_items_els([], Item) ->
+    lists:reverse(Item).
+
+decode_pubsub_items_items_attrs([{<<"subid">>, _val}
+                                | _attrs],
+                               _Subid, Max_items, Node) ->
+    decode_pubsub_items_items_attrs(_attrs, _val, Max_items,
+                                   Node);
+decode_pubsub_items_items_attrs([{<<"max_items">>, _val}
+                                | _attrs],
+                               Subid, _Max_items, Node) ->
+    decode_pubsub_items_items_attrs(_attrs, Subid, _val,
+                                   Node);
+decode_pubsub_items_items_attrs([{<<"node">>, _val}
+                                | _attrs],
+                               Subid, Max_items, _Node) ->
+    decode_pubsub_items_items_attrs(_attrs, Subid,
+                                   Max_items, _val);
+decode_pubsub_items_items_attrs([_ | _attrs], Subid,
+                               Max_items, Node) ->
+    decode_pubsub_items_items_attrs(_attrs, Subid,
+                                   Max_items, Node);
+decode_pubsub_items_items_attrs([], Subid, Max_items,
+                               Node) ->
+    {decode_pubsub_items_items_subid(Subid),
+     decode_pubsub_items_items_max_items(Max_items),
+     decode_pubsub_items_items_node(Node)}.
+
+encode_pubsub_items_items([], _acc) -> _acc;
+encode_pubsub_items_items([{pubsub_items, Node,
+                           Max_items, Subid, Item}
+                          | _tail],
+                         _acc) ->
+    _els = encode_pubsub_item_item(Item, []),
+    _attrs = encode_pubsub_items_items_node(Node,
+                                           encode_pubsub_items_items_max_items(Max_items,
+                                                                               encode_pubsub_items_items_subid(Subid,
+                                                                                                               []))),
+    encode_pubsub_items_items(_tail,
+                             [{xmlel, <<"items">>, _attrs, _els} | _acc]).
+
+decode_pubsub_items_items_max_items(undefined) ->
+    undefined;
+decode_pubsub_items_items_max_items(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"max_items">>,
+                       <<"items">>, <<>>});
+      _res -> _res
+    end.
+
+encode_pubsub_items_items_max_items(undefined, _acc) ->
+    _acc;
+encode_pubsub_items_items_max_items(_val, _acc) ->
+    [{<<"max_items">>, xml_gen:enc_int(_val)} | _acc].
+
+decode_pubsub_items_items_node(undefined) ->
+    erlang:error({missing_attr, <<"node">>, <<"items">>,
+                 <<>>});
+decode_pubsub_items_items_node(_val) -> _val.
+
+encode_pubsub_items_items_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_pubsub_items_items_subid(undefined) -> undefined;
+decode_pubsub_items_items_subid(_val) -> _val.
+
+encode_pubsub_items_items_subid(undefined, _acc) ->
+    _acc;
+encode_pubsub_items_items_subid(_val, _acc) ->
+    [{<<"subid">>, _val} | _acc].
+
+decode_pubsub_event_event({xmlel, _, _attrs, _els}) ->
+    Items = decode_pubsub_event_event_els(_els, []),
+    {pubsub_event, Items}.
+
+decode_pubsub_event_event_els([{xmlel, <<"items">>,
+                               _attrs, _} =
+                                  _el
+                              | _els],
+                             Items) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_event_event_els(_els,
+                                       [decode_pubsub_items_items(_el)
+                                        | Items]);
+      _ -> decode_pubsub_event_event_els(_els, Items)
+    end;
+decode_pubsub_event_event_els([_ | _els], Items) ->
+    decode_pubsub_event_event_els(_els, Items);
+decode_pubsub_event_event_els([], Items) ->
+    lists:reverse(Items).
+
+encode_pubsub_event_event(undefined, _acc) -> _acc;
+encode_pubsub_event_event({pubsub_event, Items},
+                         _acc) ->
+    _els = encode_pubsub_items_items(Items, []),
+    _attrs = [{<<"xmlns">>,
+              <<"http://jabber.org/protocol/pubsub#event">>}],
+    [{xmlel, <<"event">>, _attrs, _els} | _acc].
+
+decode_pubsub_pubsub({xmlel, _, _attrs, _els}) ->
+    {Subscribe, Publish, Affiliations, Subscriptions} =
+       decode_pubsub_pubsub_els(_els, undefined, undefined,
+                                undefined, undefined),
+    {pubsub, Subscriptions, Affiliations, Publish,
+     Subscribe}.
+
+decode_pubsub_pubsub_els([{xmlel, <<"subscribe">>,
+                          _attrs, _} =
+                             _el
+                         | _els],
+                        Subscribe, Publish, Affiliations, Subscriptions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_pubsub_els(_els,
+                                  decode_pubsub_pubsub_subscribe(_el), Publish,
+                                  Affiliations, Subscriptions);
+      _ ->
+         decode_pubsub_pubsub_els(_els, Subscribe, Publish,
+                                  Affiliations, Subscriptions)
+    end;
+decode_pubsub_pubsub_els([{xmlel, <<"publish">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Subscribe, Publish, Affiliations, Subscriptions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_pubsub_els(_els, Subscribe,
+                                  decode_pubsub_pubsub_publish(_el),
+                                  Affiliations, Subscriptions);
+      _ ->
+         decode_pubsub_pubsub_els(_els, Subscribe, Publish,
+                                  Affiliations, Subscriptions)
+    end;
+decode_pubsub_pubsub_els([{xmlel, <<"affiliations">>,
+                          _attrs, _} =
+                             _el
+                         | _els],
+                        Subscribe, Publish, Affiliations, Subscriptions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_pubsub_els(_els, Subscribe, Publish,
+                                  decode_pubsub_pubsub_affiliations(_el),
+                                  Subscriptions);
+      _ ->
+         decode_pubsub_pubsub_els(_els, Subscribe, Publish,
+                                  Affiliations, Subscriptions)
+    end;
+decode_pubsub_pubsub_els([{xmlel, <<"subscriptions">>,
+                          _attrs, _} =
+                             _el
+                         | _els],
+                        Subscribe, Publish, Affiliations, Subscriptions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_pubsub_els(_els, Subscribe, Publish,
+                                  Affiliations,
+                                  decode_pubsub_pubsub_subscriptions(_el));
+      _ ->
+         decode_pubsub_pubsub_els(_els, Subscribe, Publish,
+                                  Affiliations, Subscriptions)
+    end;
+decode_pubsub_pubsub_els([_ | _els], Subscribe, Publish,
+                        Affiliations, Subscriptions) ->
+    decode_pubsub_pubsub_els(_els, Subscribe, Publish,
+                            Affiliations, Subscriptions);
+decode_pubsub_pubsub_els([], Subscribe, Publish,
+                        Affiliations, Subscriptions) ->
+    {Subscribe, Publish, Affiliations, Subscriptions}.
+
+encode_pubsub_pubsub(undefined, _acc) -> _acc;
+encode_pubsub_pubsub({pubsub, Subscriptions,
+                     Affiliations, Publish, Subscribe},
+                    _acc) ->
+    _els = encode_pubsub_pubsub_subscriptions(Subscriptions,
+                                             encode_pubsub_pubsub_affiliations(Affiliations,
+                                                                               encode_pubsub_pubsub_publish(Publish,
+                                                                                                            encode_pubsub_pubsub_subscribe(Subscribe,
+                                                                                                                                           [])))),
+    _attrs = [{<<"xmlns">>,
+              <<"http://jabber.org/protocol/pubsub">>}],
+    [{xmlel, <<"pubsub">>, _attrs, _els} | _acc].
+
+decode_pubsub_pubsub_publish({xmlel, _, _attrs,
+                             _els}) ->
+    Node = decode_pubsub_pubsub_publish_attrs(_attrs,
+                                             undefined),
+    Item = decode_pubsub_pubsub_publish_els(_els, []),
+    {Node, Item}.
+
+decode_pubsub_pubsub_publish_els([{xmlel, <<"item">>,
+                                  _attrs, _} =
+                                     _el
+                                 | _els],
+                                Item) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_pubsub_publish_els(_els,
+                                          [decode_pubsub_item_item(_el)
+                                           | Item]);
+      _ -> decode_pubsub_pubsub_publish_els(_els, Item)
+    end;
+decode_pubsub_pubsub_publish_els([_ | _els], Item) ->
+    decode_pubsub_pubsub_publish_els(_els, Item);
+decode_pubsub_pubsub_publish_els([], Item) ->
+    lists:reverse(Item).
+
+decode_pubsub_pubsub_publish_attrs([{<<"node">>, _val}
+                                   | _attrs],
+                                  _Node) ->
+    decode_pubsub_pubsub_publish_attrs(_attrs, _val);
+decode_pubsub_pubsub_publish_attrs([_ | _attrs],
+                                  Node) ->
+    decode_pubsub_pubsub_publish_attrs(_attrs, Node);
+decode_pubsub_pubsub_publish_attrs([], Node) ->
+    decode_pubsub_pubsub_publish_node(Node).
+
+encode_pubsub_pubsub_publish(undefined, _acc) -> _acc;
+encode_pubsub_pubsub_publish({Node, Item}, _acc) ->
+    _els = encode_pubsub_item_item(Item, []),
+    _attrs = encode_pubsub_pubsub_publish_node(Node, []),
+    [{xmlel, <<"publish">>, _attrs, _els} | _acc].
+
+decode_pubsub_pubsub_publish_node(undefined) ->
+    erlang:error({missing_attr, <<"node">>, <<"publish">>,
+                 <<>>});
+decode_pubsub_pubsub_publish_node(_val) -> _val.
+
+encode_pubsub_pubsub_publish_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_pubsub_pubsub_subscribe({xmlel, _, _attrs,
+                               _els}) ->
+    {Jid, Node} =
+       decode_pubsub_pubsub_subscribe_attrs(_attrs, undefined,
+                                            undefined),
+    {Node, Jid}.
+
+decode_pubsub_pubsub_subscribe_attrs([{<<"jid">>, _val}
+                                     | _attrs],
+                                    _Jid, Node) ->
+    decode_pubsub_pubsub_subscribe_attrs(_attrs, _val,
+                                        Node);
+decode_pubsub_pubsub_subscribe_attrs([{<<"node">>, _val}
+                                     | _attrs],
+                                    Jid, _Node) ->
+    decode_pubsub_pubsub_subscribe_attrs(_attrs, Jid, _val);
+decode_pubsub_pubsub_subscribe_attrs([_ | _attrs], Jid,
+                                    Node) ->
+    decode_pubsub_pubsub_subscribe_attrs(_attrs, Jid, Node);
+decode_pubsub_pubsub_subscribe_attrs([], Jid, Node) ->
+    {decode_pubsub_pubsub_subscribe_jid(Jid),
+     decode_pubsub_pubsub_subscribe_node(Node)}.
+
+encode_pubsub_pubsub_subscribe(undefined, _acc) -> _acc;
+encode_pubsub_pubsub_subscribe({Node, Jid}, _acc) ->
+    _els = [],
+    _attrs = encode_pubsub_pubsub_subscribe_node(Node,
+                                                encode_pubsub_pubsub_subscribe_jid(Jid,
+                                                                                   [])),
+    [{xmlel, <<"subscribe">>, _attrs, _els} | _acc].
+
+decode_pubsub_pubsub_subscribe_node(undefined) ->
+    undefined;
+decode_pubsub_pubsub_subscribe_node(_val) -> _val.
+
+encode_pubsub_pubsub_subscribe_node(undefined, _acc) ->
+    _acc;
+encode_pubsub_pubsub_subscribe_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_pubsub_pubsub_subscribe_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"subscribe">>,
+                 <<>>});
+decode_pubsub_pubsub_subscribe_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>,
+                       <<"subscribe">>, <<>>});
+      _res -> _res
+    end.
+
+encode_pubsub_pubsub_subscribe_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
+
+decode_pubsub_pubsub_affiliations({xmlel, _, _attrs,
+                                  _els}) ->
+    Pubsub_affiliations =
+       decode_pubsub_pubsub_affiliations_els(_els, []),
+    Pubsub_affiliations.
+
+decode_pubsub_pubsub_affiliations_els([{xmlel,
+                                       <<"affiliation">>, _attrs, _} =
+                                          _el
+                                      | _els],
+                                     Pubsub_affiliations) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_pubsub_affiliations_els(_els,
+                                               [decode_pubsub_affiliation_affiliation(_el)
+                                                | Pubsub_affiliations]);
+      _ ->
+         decode_pubsub_pubsub_affiliations_els(_els,
+                                               Pubsub_affiliations)
+    end;
+decode_pubsub_pubsub_affiliations_els([_ | _els],
+                                     Pubsub_affiliations) ->
+    decode_pubsub_pubsub_affiliations_els(_els,
+                                         Pubsub_affiliations);
+decode_pubsub_pubsub_affiliations_els([],
+                                     Pubsub_affiliations) ->
+    lists:reverse(Pubsub_affiliations).
+
+encode_pubsub_pubsub_affiliations(undefined, _acc) ->
+    _acc;
+encode_pubsub_pubsub_affiliations(Pubsub_affiliations,
+                                 _acc) ->
+    _els =
+       encode_pubsub_affiliation_affiliation(Pubsub_affiliations,
+                                             []),
+    _attrs = [],
+    [{xmlel, <<"affiliations">>, _attrs, _els} | _acc].
+
+decode_pubsub_pubsub_subscriptions({xmlel, _, _attrs,
+                                   _els}) ->
+    Node = decode_pubsub_pubsub_subscriptions_attrs(_attrs,
+                                                   undefined),
+    Pubsub_subscriptions =
+       decode_pubsub_pubsub_subscriptions_els(_els, []),
+    {Node, Pubsub_subscriptions}.
+
+decode_pubsub_pubsub_subscriptions_els([{xmlel,
+                                        <<"subscription">>, _attrs, _} =
+                                           _el
+                                       | _els],
+                                      Pubsub_subscriptions) ->
+    case xml:get_attr_s(<<"xmlns">>, _attrs) of
+      <<>> ->
+         decode_pubsub_pubsub_subscriptions_els(_els,
+                                                [decode_pubsub_subscription_subscription(_el)
+                                                 | Pubsub_subscriptions]);
+      _ ->
+         decode_pubsub_pubsub_subscriptions_els(_els,
+                                                Pubsub_subscriptions)
+    end;
+decode_pubsub_pubsub_subscriptions_els([_ | _els],
+                                      Pubsub_subscriptions) ->
+    decode_pubsub_pubsub_subscriptions_els(_els,
+                                          Pubsub_subscriptions);
+decode_pubsub_pubsub_subscriptions_els([],
+                                      Pubsub_subscriptions) ->
+    lists:reverse(Pubsub_subscriptions).
+
+decode_pubsub_pubsub_subscriptions_attrs([{<<"node">>,
+                                          _val}
+                                         | _attrs],
+                                        _Node) ->
+    decode_pubsub_pubsub_subscriptions_attrs(_attrs, _val);
+decode_pubsub_pubsub_subscriptions_attrs([_ | _attrs],
+                                        Node) ->
+    decode_pubsub_pubsub_subscriptions_attrs(_attrs, Node);
+decode_pubsub_pubsub_subscriptions_attrs([], Node) ->
+    decode_pubsub_pubsub_subscriptions_node(Node).
+
+encode_pubsub_pubsub_subscriptions(undefined, _acc) ->
+    _acc;
+encode_pubsub_pubsub_subscriptions({Node,
+                                   Pubsub_subscriptions},
+                                  _acc) ->
+    _els =
+       encode_pubsub_subscription_subscription(Pubsub_subscriptions,
+                                               []),
+    _attrs = encode_pubsub_pubsub_subscriptions_node(Node,
+                                                    []),
+    [{xmlel, <<"subscriptions">>, _attrs, _els} | _acc].
+
+decode_pubsub_pubsub_subscriptions_node(undefined) ->
+    none;
+decode_pubsub_pubsub_subscriptions_node(_val) -> _val.
+
+encode_pubsub_pubsub_subscriptions_node(none, _acc) ->
+    _acc;
+encode_pubsub_pubsub_subscriptions_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_delay_delay({xmlel, _, _attrs, _els}) ->
+    {From, Stamp} = decode_delay_delay_attrs(_attrs,
+                                            undefined, undefined),
+    {delay, Stamp, From}.
+
+decode_delay_delay_attrs([{<<"from">>, _val} | _attrs],
+                        _From, Stamp) ->
+    decode_delay_delay_attrs(_attrs, _val, Stamp);
+decode_delay_delay_attrs([{<<"stamp">>, _val} | _attrs],
+                        From, _Stamp) ->
+    decode_delay_delay_attrs(_attrs, From, _val);
+decode_delay_delay_attrs([_ | _attrs], From, Stamp) ->
+    decode_delay_delay_attrs(_attrs, From, Stamp);
+decode_delay_delay_attrs([], From, Stamp) ->
+    {decode_delay_delay_from(From),
+     decode_delay_delay_stamp(Stamp)}.
+
+encode_delay_delay(undefined, _acc) -> _acc;
+encode_delay_delay({delay, Stamp, From}, _acc) ->
+    _els = [],
+    _attrs = encode_delay_delay_stamp(Stamp,
+                                     encode_delay_delay_from(From,
+                                                             [{<<"xmlns">>,
+                                                               <<"urn:xmpp:delay">>}])),
+    [{xmlel, <<"delay">>, _attrs, _els} | _acc].
+
+decode_delay_delay_stamp(undefined) ->
+    erlang:error({missing_attr, <<"stamp">>, <<"delay">>,
+                 <<"urn:xmpp:delay">>});
+decode_delay_delay_stamp(_val) ->
+    case catch dec_utc(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"stamp">>, <<"delay">>,
+                       <<"urn:xmpp:delay">>});
+      _res -> _res
+    end.
+
+encode_delay_delay_stamp(_val, _acc) ->
+    [{<<"stamp">>, enc_utc(_val)} | _acc].
+
+decode_delay_delay_from(undefined) -> undefined;
+decode_delay_delay_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"delay">>,
+                       <<"urn:xmpp:delay">>});
+      _res -> _res
+    end.
+
+encode_delay_delay_from(undefined, _acc) -> _acc;
+encode_delay_delay_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
diff --git a/tools/xmpp_codec.hrl b/tools/xmpp_codec.hrl
new file mode 100644 (file)
index 0000000..9c0e456
--- /dev/null
@@ -0,0 +1,168 @@
+-record(last, {seconds, text}).
+
+-record(version, {name, version, os}).
+
+-record(roster, {item = [], ver}).
+
+-record(roster_item,
+       {jid, name, groups = [], subscription = none, ask}).
+
+-record(privacy_item,
+       {order, action, type, value, stanza}).
+
+-record(privacy, {list = [], default, active}).
+
+-record(privacy_list, {name, privacy_item = []}).
+
+-record(block, {block_item = []}).
+
+-record(unblock, {block_item = []}).
+
+-record(block_list, {}).
+
+-record(disco_info,
+       {node, identity = [], feature = [], xdata = []}).
+
+-record(disco_items, {node, items = []}).
+
+-record(disco_item, {jid, name, node}).
+
+-record(private, {sub_els = []}).
+
+-record(bookmark_conference,
+       {name, jid, autojoin = false, nick, password}).
+
+-record(bookmark_storage, {conference = [], url = []}).
+
+-record(bookmark_url, {name, url}).
+
+-record(stats, {stat = []}).
+
+-record(stat, {name, units, value, error = []}).
+
+-record(iq,
+       {id, type, lang, from, to, error, sub_els = []}).
+
+-record(message,
+       {id, type = normal, lang, from, to, subject = [],
+        body = [], thread, error, sub_els = []}).
+
+-record(presence,
+       {id, type, lang, from, to, show, status = [], priority,
+        error, sub_els = []}).
+
+-record(error, {error_type, by, reason, text}).
+
+-record(redirect, {cdata}).
+
+-record(gone, {cdata}).
+
+-record(bind, {jid, resource}).
+
+-record(sasl_auth, {mechanism, cdata}).
+
+-record(sasl_abort, {}).
+
+-record(sasl_challenge, {cdata}).
+
+-record(sasl_response, {cdata}).
+
+-record(sasl_success, {cdata}).
+
+-record(sasl_failure, {reason, text}).
+
+-record(sasl_mechanisms, {mechanism = []}).
+
+-record(starttls, {required = false}).
+
+-record(starttls_proceed, {}).
+
+-record(starttls_failure, {}).
+
+-record(stream_features, {sub_els = []}).
+
+-record(p1_push, {}).
+
+-record(p1_rebind, {}).
+
+-record(p1_ack, {}).
+
+-record(caps, {hash, node, ver}).
+
+-record(register, {}).
+
+-record(session, {}).
+
+-record(ping, {}).
+
+-record(time, {tzo, utc}).
+
+-record(stream_error, {reason, text}).
+
+-record('see-other-host', {cdata}).
+
+-record(vcard_name,
+       {family, given, middle, prefix, suffix}).
+
+-record(vcard_adr,
+       {home = false, work = false, postal = false,
+        parcel = false, dom = false, intl = false, pref = false,
+        pobox, extadd, street, locality, region, pcode, ctry}).
+
+-record(vcard_label,
+       {home = false, work = false, postal = false,
+        parcel = false, dom = false, intl = false, pref = false,
+        line = []}).
+
+-record(vcard_tel,
+       {home = false, work = false, voice = false, fax = false,
+        pager = false, msg = false, cell = false, video = false,
+        bbs = false, modem = false, isdn = false, pcs = false,
+        pref = false, number}).
+
+-record(vcard_email,
+       {home = false, work = false, internet = false,
+        pref = false, x400 = false, userid}).
+
+-record(vcard_geo, {lat, lon}).
+
+-record(vcard_logo, {type, binval, extval}).
+
+-record(vcard_photo, {type, binval, extval}).
+
+-record(vcard_org, {name, units = []}).
+
+-record(vcard_sound, {phonetic, binval, extval}).
+
+-record(vcard_key, {type, cred}).
+
+-record(vcard,
+       {version, fn, n, nickname, photo, bday, adr = [],
+        label = [], tel = [], email = [], jabberid, mailer, tz,
+        geo, title, role, logo, org, categories = [], note,
+        prodid, rev, 'sort-string', sound, uid, url, class, key,
+        desc}).
+
+-record(xfield,
+       {label, type, var, required = false, desc, values = [],
+        options = []}).
+
+-record(xdata,
+       {type, instructions = [], title, reported, items = [],
+        fields = []}).
+
+-record(pubsub_subscription, {jid, node, subid, type}).
+
+-record(pubsub_affiliation, {node, type}).
+
+-record(pubsub_item, {id, sub_els = []}).
+
+-record(pubsub_items,
+       {node, max_items, subid, item = []}).
+
+-record(pubsub_event, {items = []}).
+
+-record(pubsub,
+       {subscriptions, affiliations, publish, subscribe}).
+
+-record(delay, {stamp, from}).
diff --git a/tools/xmpp_codec.spec b/tools/xmpp_codec.spec
new file mode 100644 (file)
index 0000000..ebcb77e
--- /dev/null
@@ -0,0 +1,1244 @@
+{spec, last,
+ #spec{name = <<"query">>,
+       min = 0, max = 1,
+       xmlns = <<"jabber:iq:last">>,
+       result = {last, '$seconds', '$text'},
+       attrs = [#attr{name = <<"seconds">>,
+                      default = undefined,
+                      enc = {enc_int, []},
+                      dec = {dec_int, [0, infinity]}}],
+       cdata = #cdata{label = '$text'}}}.
+
+{spec, version,
+ #spec{name = <<"query">>,
+       xmlns = <<"jabber:iq:version">>,
+       min = 0, max = 1,
+       result = {version, '$name', '$version', '$os'},
+       els = [#spec{name = <<"name">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{label = '$cdata', required = true}},
+              #spec{name = <<"version">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{label = '$cdata', required = true}},
+              #spec{name = <<"os">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{label = '$cdata', required = true}}]}}.
+
+{spec, roster,
+ #spec{name = <<"query">>,
+       xmlns = <<"jabber:iq:roster">>,
+       result = {roster, '$item', '$ver'},
+       min = 0, max = 1,
+       attrs = [#attr{name = <<"ver">>}],
+       els = [#spec{name = <<"item">>,
+                    result = {roster_item, '$jid', '$name',
+                              '$groups', '$subscription', '$ask'},
+                    attrs = [#attr{name = <<"jid">>,
+                                   required = true,
+                                   dec = {dec_jid, []},
+                                   enc = {enc_jid, []}},
+                             #attr{name = <<"name">>},
+                             #attr{name = <<"subscription">>,
+                                   default = none,
+                                   enc = {enc_enum, []},
+                                   dec = {dec_enum, [[none,to,from,both,remove]]}},
+                             #attr{name = <<"ask">>,
+                                   default = undefined,
+                                   enc = {enc_enum, []},
+                                   dec = {dec_enum, [[subscribe]]}}],
+                    els = [#spec{name = <<"group">>,
+                                 label = '$groups',
+                                 result = '$cdata',
+                                 cdata = #cdata{required = true,
+                                                label = '$cdata'}}]}]}}.
+
+{spec, privacy_item,
+ #spec{name = <<"item">>,
+       result = {privacy_item, '$order', '$action', '$type',
+                 '$value', '$stanza'},
+       label = '$privacy_item',
+       attrs = [#attr{name = <<"action">>,
+                      required = true,
+                      dec = {dec_enum, [[allow, deny]]},
+                      enc = {enc_enum, []}},
+                #attr{name = <<"order">>,
+                      required = true,
+                      dec = {dec_int, [0, infinity]},
+                      enc = {enc_int, []}},
+                #attr{name = <<"type">>,
+                      dec = {dec_enum, [[group, jid, subscription]]},
+                      enc = {enc_enum, []}},
+                #attr{name = <<"value">>}],
+       els = [#spec{name = <<"message">>,
+                    min = 0, max = 1,
+                    label = '$stanza',
+                    result = message},
+              #spec{name = <<"iq">>,
+                    min = 0, max = 1,
+                    label = '$stanza',
+                    result = iq},
+              #spec{name = <<"presence-in">>,
+                    min = 0, max = 1,
+                    label = '$stanza',
+                    result = 'presence-in'},
+              #spec{name = <<"presence-out">>,
+                    min = 0, max = 1,
+                    label = '$stanza',
+                    result = 'presence-out'}]}}.
+
+{spec, privacy,
+ #spec{name = <<"query">>,
+       min = 0, max = 1,
+       xmlns = <<"jabber:iq:privacy">>,
+       result = {privacy, '$list', '$default', '$active'},
+       els = [#spec{name = <<"list">>,
+                    result = {privacy_list, '$name', '$privacy_item'},
+                    attrs = [#attr{name = <<"name">>,
+                                   required = true}],
+                    els = [privacy_item]},
+              #spec{name = <<"default">>,
+                    min = 0, max = 1,
+                    result = '$name',
+                    attrs = [#attr{name = <<"name">>,
+                                   default = none}]},
+              #spec{name = <<"active">>,
+                    min = 0, max = 1,
+                    result = '$name',
+                    attrs = [#attr{name = <<"name">>,
+                                   default = none}]}]}}.
+
+{spec, block_item,
+ #spec{name = <<"item">>,
+       label = '$block_item',
+       result = '$jid',
+       attrs = [#attr{name = <<"jid">>,
+                      required = true,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}}]}}.
+
+{spec, block,
+ #spec{name = <<"block">>,
+       xmlns = <<"urn:xmpp:blocking">>,
+       min = 0, max = 1,
+       result = {block, '$block_item'},
+       els = [block_item]}}.
+
+{spec, unblock,
+ #spec{name = <<"unblock">>,
+       xmlns = <<"urn:xmpp:blocking">>,
+       min = 0, max = 1,
+       result = {unblock, '$block_item'},
+       els = [block_item]}}.
+
+{spec, block_list,
+ #spec{name = <<"blocklist">>,
+       xmlns = <<"urn:xmpp:blocking">>,
+       result = {block_list},
+       min = 0, max = 1}}.
+
+{spec, disco_info,
+ #spec{name = <<"query">>,
+       min = 0, max = 1,
+       xmlns = <<"http://jabber.org/protocol/disco#info">>,
+       result = {disco_info, '$node', '$identity', '$feature', '$xdata'},
+       attrs = [#attr{name = <<"node">>}],
+       els = [#spec{name = <<"identity">>,
+                    result = {'$category', '$type', '$name'},
+                    attrs = [#attr{name = <<"category">>,
+                                   required = true},
+                             #attr{name = <<"type">>,
+                                   required = true},
+                             #attr{name = <<"name">>}]},
+              #spec{name = <<"feature">>,
+                    result = '$var',
+                    attrs = [#attr{name = <<"var">>,
+                                   required = true}]},
+              xdata]}}.
+
+{spec, disco_items,
+ #spec{name = <<"query">>,
+       min = 0, max = 1,
+       xmlns = <<"http://jabber.org/protocol/disco#items">>,
+       result = {disco_items, '$node', '$items'},
+       attrs = [#attr{name = <<"node">>}],
+       els = [#spec{name = <<"item">>,
+                    label = '$items',
+                    result = {disco_item, '$jid', '$name', '$node'},
+                    cdata = #cdata{label = '$cdata'},
+                    attrs = [#attr{name = <<"jid">>,
+                                   dec = {dec_jid, []},
+                                   enc = {enc_jid, []},
+                                   required = true},
+                             #attr{name = <<"name">>},
+                             #attr{name = <<"node">>}]}]}}.
+
+{spec, private,
+ #spec{name = <<"query">>,
+       min = 0, max = 1,
+       xmlns = <<"jabber:iq:private">>,
+       result = {private, '$_els'}}}.
+
+{spec, bookmark_conference,
+ #spec{name = <<"conference">>,
+       result = {bookmark_conference, '$name', '$jid',
+                 '$autojoin', '$nick', '$password'},
+       attrs = [#attr{name = <<"name">>,
+                      required = true},
+                #attr{name = <<"jid">>,
+                      required = true,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"autojoin">>,
+                      default = false,
+                      dec = {dec_bool, []},
+                      enc = {enc_bool, []}}],
+       els = [#spec{name = <<"nick">>,
+                    min = 0, max = 1,
+                    result = '$cdata'},
+              #spec{name = <<"password">>,
+                    min = 0, max = 1,
+                    result = '$cdata'}]}}.
+
+{spec, storage_bookmarks,
+ #spec{name = <<"storage">>,
+       xmlns = <<"storage:bookmarks">>,
+       min = 0, max = 1,
+       result = {bookmark_storage, '$conference', '$url'},
+       els = [bookmark_conference,
+              #spec{name = <<"url">>,
+                    result = {bookmark_url, '$name', '$url'},
+                    attrs = [#attr{name = <<"name">>,
+                                   required = true},
+                             #attr{name = <<"url">>,
+                                   required = true}]}]}}.
+
+{spec, stats,
+ #spec{name = <<"query">>,
+       min = 0, max = 1,
+       xmlns = <<"http://jabber.org/protocol/stats">>,
+       result = {stats, '$stat'},
+       els = [#spec{name = <<"stat">>,
+                    result = {stat, '$name', '$units', '$value', '$error'},
+                    attrs = [#attr{name = <<"name">>,
+                                   required = true},
+                             #attr{name = <<"units">>},
+                             #attr{name = <<"value">>}],
+                    els = [#spec{name = <<"error">>,
+                                 result = {'$code', '$cdata'},
+                                 attrs = [#attr{name = <<"code">>,
+                                                required = true,
+                                                enc = {enc_int, []},
+                                                dec = {dec_int, []}}]}]}]}}.
+
+{spec, iq,
+ #spec{name = <<"iq">>,
+       min = 0, max = 1,
+       result = {iq, '$id', '$type', '$lang', '$from', '$to',
+                 '$error', '$_els'},
+       attrs = [#attr{name = <<"id">>,
+                      required = true},
+                #attr{name = <<"type">>,
+                      required = true,
+                      enc = {enc_enum, []},
+                      dec = {dec_enum, [[get, set, result, error]]}},
+                #attr{name = <<"from">>,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"to">>,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"xml:lang">>,
+                      label = '$lang'}],
+       els = [error]}}.
+
+{spec, message,
+ #spec{name = <<"message">>,
+       min = 0, max = 1,
+       result = {message, '$id', '$type', '$lang', '$from', '$to',
+                 '$subject', '$body', '$thread', '$error', '$_els'},
+       attrs = [#attr{name = <<"id">>},
+                #attr{name = <<"type">>,
+                      default = normal,
+                      enc = {enc_enum, []},
+                      dec = {dec_enum, [[chat, normal, groupchat,
+                                         headline, error]]}},
+                #attr{name = <<"from">>,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"to">>,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"xml:lang">>,
+                      label = '$lang'}],
+       els = [error,
+              #spec{name = <<"subject">>,
+                    result = {'$subject_lang', '$cdata'},
+                    attrs = [#attr{name = <<"xml:lang">>,
+                                   label = '$subject_lang'}]},
+              #spec{name = <<"body">>,
+                    result = {'$body_lang', '$cdata'},
+                    attrs = [#attr{name = <<"xml:lang">>,
+                                   label = '$body_lang'}]},
+              #spec{name = <<"thread">>,
+                    min = 0, max = 1,
+                    result = '$cdata'}]}}.
+
+{spec, presence,
+ #spec{name = <<"presence">>,
+       min = 0, max = 1,
+       result = {presence, '$id', '$type', '$lang', '$from', '$to',
+                 '$show', '$status', '$priority', '$error', '$_els'},
+       attrs = [#attr{name = <<"id">>},
+                #attr{name = <<"type">>,
+                      enc = {enc_enum, []},
+                      dec = {dec_enum, [[unavailable, subscribe, subscribed,
+                                         unsubscribe, unsubscribed,
+                                         probe, error]]}},
+                #attr{name = <<"from">>,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"to">>,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"xml:lang">>,
+                      label = '$lang'}],
+       els = [error,
+              #spec{name = <<"show">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{enc = {enc_enum, []},
+                                   dec = {dec_enum, [[away, chat, dnd, xa]]}}},
+              #spec{name = <<"status">>,
+                    result = {'$status_lang', '$cdata'},
+                    attrs = [#attr{name = <<"xml:lang">>,
+                                   label = '$status_lang'}]},
+              #spec{name = <<"priority">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{enc = {enc_int, []},
+                                   dec = {dec_int, [-128, 127]}}}]}}.
+
+{spec, error,
+ #spec{name = <<"error">>,
+       min = 0, max = 1,
+       result = {error, '$error_type', '$by', '$reason', '$text'},
+       attrs = [#attr{name = <<"type">>,
+                      label = '$error_type',
+                      required = true,
+                      dec = {dec_enum, [[auth, cancel, continue,
+                                         modify, wait]]},
+                      enc = {enc_enum, []}},
+                #attr{name = <<"by">>}],
+       els = [#spec{name = <<"text">>,
+                    min = 0, max = 1,
+                    result = {'$text_lang', '$cdata'},
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    attrs = [#attr{name = <<"xml:lang">>,
+                                   label = '$text_lang'}]},
+              #spec{name = <<"bad-request">>, 
+                    result = 'bad-request',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"conflict">>, 
+                    result = 'conflict',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"feature-not-implemented">>, 
+                    result = 'feature-not-implemented',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"forbidden">>, 
+                    result = 'forbidden',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"gone">>, 
+                    result = {'gone', '$cdata'},
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"internal-server-error">>, 
+                    result = 'internal-server-error',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"item-not-found">>, 
+                    result = 'item-not-found',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"jid-malformed">>, 
+                    result = 'jid-malformed',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"not-acceptable">>, 
+                    result = 'not-acceptable',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"not-allowed">>, 
+                    result = 'not-allowed',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"not-authorized">>, 
+                    result = 'not-authorized',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"policy-violation">>, 
+                    result = 'policy-violation',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"recipient-unavailable">>, 
+                    result = 'recipient-unavailable',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"redirect">>, 
+                    result = {'redirect', '$cdata'},
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"registration-required">>, 
+                    result = 'registration-required',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"remote-server-not-found">>, 
+                    result = 'remote-server-not-found',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"remote-server-timeout">>, 
+                    result = 'remote-server-timeout',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"resource-constraint">>, 
+                    result = 'resource-constraint',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"service-unavailable">>, 
+                    result = 'service-unavailable',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"subscription-required">>, 
+                    result = 'subscription-required',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"undefined-condition">>, 
+                    result = 'undefined-condition',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"unexpected-request">>, 
+                    result = 'unexpected-request',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-stanzas">>,
+                    min = 0, max = 1, label = '$reason'}]}}.
+                     
+{spec, bind,
+ #spec{name = <<"bind">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-bind">>,
+       min = 0, max = 1,
+       result = {bind, '$jid', '$resource'},
+       els = [#spec{name = <<"jid">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{dec = {dec_jid, []},
+                                   enc = {enc_jid, []}}},
+              #spec{name = <<"resource">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{dec = {resourceprep, []},
+                                   enc = {resourceprep, []}}}]}}.
+
+{spec, sasl_auth,
+ #spec{name = <<"auth">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+       min = 0, max = 1,
+       cdata = #cdata{dec = {base64, decode, []},
+                      enc = {base64, encode, []}},
+       result = {sasl_auth, '$mechanism', '$cdata'},
+       attrs = [#attr{name = <<"mechanism">>,
+                      required = true}]}}.
+
+{spec, sasl_abort,
+ #spec{name = <<"abort">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+       min = 0, max = 1,
+       result = {sasl_abort}}}.
+
+{spec, sasl_challenge,
+ #spec{name = <<"challenge">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+       min = 0, max = 1,
+       cdata = #cdata{dec = {base64, decode, []},
+                      enc = {base64, encode, []}},
+       result = {sasl_challenge, '$cdata'}}}.
+
+{spec, sasl_response,
+ #spec{name = <<"response">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+       min = 0, max = 1,
+       cdata = #cdata{dec = {base64, decode, []},
+                      enc = {base64, encode, []}},
+       result = {sasl_response, '$cdata'}}}.
+
+{spec, sasl_success,
+ #spec{name = <<"success">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+       min = 0, max = 1,
+       cdata = #cdata{dec = {base64, decode, []},
+                      enc = {base64, encode, []}},
+       result = {sasl_success, '$cdata'}}}.
+
+{spec, sasl_failure,
+ #spec{name = <<"failure">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+       min = 0, max = 1,
+       result = {sasl_failure, '$reason', '$text'},
+       els = [#spec{name = <<"text">>,
+                    min = 0, max = 1,
+                    result = {'$text_lang', '$cdata'},
+                    attrs = [#attr{name = <<"xml:lang">>,
+                                   label = '$text_lang'}]},
+              #spec{name = <<"aborted">>,
+                    result = 'aborted',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"account-disabled">>,
+                    result = 'account-disabled',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"credentials-expired">>,
+                    result = 'credentials-expired',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"encryption-required">>,
+                    result = 'encryption-required',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"incorrect-encoding">>,
+                    result = 'incorrect-encoding',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"invalid-authzid">>,
+                    result = 'invalid-authzid',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"invalid-mechanism">>,
+                    result = 'invalid-mechanism',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"malformed-request">>,
+                    result = 'malformed-request',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"mechanism-too-weak">>,
+                    result = 'mechanism-too-weak',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"not-authorized">>,
+                    result = 'not-authorized',
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"temporary-auth-failure">>,
+                    result = 'temporary-auth-failure',
+                    min = 0, max = 1, label = '$reason'}]}}.
+
+{spec, sasl_mechanism,
+ #spec{name = <<"mechanism">>,
+       result = '$cdata',
+       min = 1,
+       cdata = #cdata{}}}.
+
+{spec, sasl_mechanisms,
+ #spec{name = <<"mechanisms">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-sasl">>,
+       result = {sasl_mechanisms, '$mechanism'},
+       min = 0, max = 1,
+       els = [sasl_mechanism]}}.
+
+{spec, starttls,
+ #spec{name = <<"starttls">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-tls">>,
+       min = 0, max = 1,
+       result = {starttls, '$required'},
+       els = [#spec{name = <<"required">>,
+                    min = 0, max = 1,
+                    default = false,
+                    result = true}]}}.
+
+{spec, starttls_proceed,
+ #spec{name = <<"proceed">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-tls">>,
+       min = 0, max = 1,
+       result = {starttls_proceed}}}.
+
+{spec, starttls_failure,
+ #spec{name = <<"failure">>,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-tls">>,
+       min = 0, max = 1,
+       result = {starttls_failure}}}.
+
+{spec, stream_features,
+ #spec{name = <<"stream:features">>,
+       min = 0, max = 1,
+       result = {stream_features, '$_els'}}}.
+
+{spec, p1_push,
+ #spec{name = <<"push">>,
+       min = 0, max = 1,
+       result = {p1_push},
+       xmlns = <<"p1:push">>}}.
+
+{spec, p1_rebind,
+ #spec{name = <<"rebind">>,
+       min = 0, max = 1,
+       result = {p1_rebind},
+       xmlns = <<"p1:rebind">>}}.
+
+{spec, p1_ack,
+ #spec{name = <<"ack">>,
+       min = 0, max = 1,
+       result = {p1_ack},
+       xmlns = <<"p1:ack">>}}.
+
+{spec, caps,
+ #spec{name = <<"c">>,
+       min = 0, max = 1,
+       xmlns = <<"http://jabber.org/protocol/caps">>,
+       result = {caps, '$hash', '$node', '$ver'},
+       attrs = [#attr{name = <<"hash">>},
+                #attr{name = <<"node">>},
+                #attr{name = <<"ver">>,
+                      enc = {base64, encode, []},
+                      dec = {base64, decode, []}}]}}.
+
+{spec, register,
+ #spec{name = <<"register">>,
+       min = 0, max = 1,
+       xmlns = <<"http://jabber.org/features/iq-register">>,
+       result = {register}}}.
+
+{spec, session,
+ #spec{name = <<"session">>,
+       min = 0, max = 1,
+       xmlns = <<"urn:ietf:params:xml:ns:xmpp-session">>,
+       result = {session}}}.
+
+{spec, ping,
+ #spec{name = <<"ping">>,
+       min = 0, max = 1,
+       xmlns = <<"urn:xmpp:ping">>,
+       result = {ping}}}.
+
+{spec, time,
+ #spec{name = <<"time">>,
+       min = 0, max = 1,
+       xmlns = <<"urn:xmpp:time">>,
+       result = {time, '$tzo', '$utc'},
+       els = [#spec{name = <<"tzo">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{dec = {dec_tzo, []},
+                                   enc = {enc_tzo, []}}},
+              #spec{name = <<"utc">>,
+                    min = 0, max = 1,
+                    result = '$cdata',
+                    cdata = #cdata{dec = {dec_utc, []},
+                                   enc = {enc_utc, []}}}]}}.
+
+{spec, stream_error,
+ #spec{name = <<"stream:error">>,
+       min = 0, max = 1,
+       result = {stream_error, '$reason', '$text'},
+       els = [#spec{name = <<"text">>,
+                    min = 0, max = 1,
+                    result = {'$text_lang', '$cdata'},
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    attrs = [#attr{name = <<"xml:lang">>,
+                                   label = '$text_lang'}]},
+              #spec{name = <<"bad-format">>,
+                    result = 'bad-format',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"bad-namespace-prefix">>,
+                    result = 'bad-namespace-prefix',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"conflict">>,
+                    result = 'conflict',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"connection-timeout">>,
+                    result = 'connection-timeout',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"host-gone">>,
+                    result = 'host-gone',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"host-unknown">>,
+                    result = 'host-unknown',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"improper-addressing">>,
+                    result = 'improper-addressing',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"internal-server-error">>,
+                    result = 'internal-server-error',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"invalid-from">>,
+                    result = 'invalid-from',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"invalid-id">>,
+                    result = 'invalid-id',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"invalid-namespace">>,
+                    result = 'invalid-namespace',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"invalid-xml">>,
+                    result = 'invalid-xml',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"not-authorized">>,
+                    result = 'not-authorized',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"not-well-formed">>,
+                    result = 'not-well-formed',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"policy-violation">>,
+                    result = 'policy-violation',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"remote-connection-failed">>,
+                    result = 'remote-connection-failed',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"reset">>,
+                    result = 'reset',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"resource-constraint">>,
+                    result = 'resource-constraint',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"restricted-xml">>,
+                    result = 'restricted-xml',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"see-other-host">>,
+                    result = {'see-other-host', '$cdata'},
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"system-shutdown">>,
+                    result = 'system-shutdown',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"undefined-condition">>,
+                    result = 'undefined-condition',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"unsupported-encoding">>,
+                    result = 'unsupported-encoding',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"unsupported-stanza-type">>,
+                    result = 'unsupported-stanza-type',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'},
+              #spec{name = <<"unsupported-version">>,
+                    result = 'unsupported-version',
+                    xmlns = <<"urn:ietf:params:xml:ns:xmpp-streams">>,
+                    min = 0, max = 1, label = '$reason'}
+             ]}}.
+
+{spec, vcard_name,
+ #spec{name = <<"N">>, label = '$n',
+       min = 0, max = 1,
+       result = {vcard_name, '$family', '$given', '$middle',
+                 '$prefix', '$suffix'},
+       els = [#spec{name = <<"FAMILY">>, label = '$family',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"GIVEN">>, label = '$given',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"MIDDLE">>, label = '$middle',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"PREFIX">>, label = '$prefix',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"SUFFIX">>, label = '$suffix',
+                    min = 0, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_adr,
+ #spec{name = <<"ADR">>, label = '$adr',
+       result = {vcard_adr, '$home', '$work', '$postal', '$parcel',
+                '$dom', '$intl', '$pref', '$pobox', '$extadd', '$street',
+                '$locality', '$region', '$pcode', '$ctry'},
+       els = [#spec{name = <<"HOME">>, label = '$home',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"WORK">>, label = '$work',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"POSTAL">>, label = '$postal',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PARCEL">>, label = '$parcel',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"DOM">>, label = '$dom',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"INTL">>, label = '$intl',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PREF">>, label = '$pref',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"POBOX">>, label = '$pobox',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"EXTADD">>, label = '$extadd',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"STREET">>, label = '$street',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"LOCALITY">>, label = '$locality',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"REGION">>, label = '$region',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"PCODE">>, label = '$pcode',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"CTRY">>, label = '$ctry',
+                    min = 0, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_label,
+ #spec{name = <<"LABEL">>, label = '$label',
+       result = {vcard_label, '$home', '$work', '$postal', '$parcel',
+                '$dom', '$intl', '$pref', '$line'},
+       els = [#spec{name = <<"HOME">>, label = '$home',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"WORK">>, label = '$work',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"POSTAL">>, label = '$postal',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PARCEL">>, label = '$parcel',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"DOM">>, label = '$dom',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"INTL">>, label = '$intl',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PREF">>, label = '$pref',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"LINE">>, label = '$line',
+                    result = '$cdata'}]}}.
+
+{spec, vcard_tel,
+ #spec{name = <<"TEL">>, label = '$tel',
+       result = {vcard_tel, '$home', '$work', '$voice', '$fax',
+                 '$pager', '$msg', '$cell', '$video', '$bbs',
+                 '$modem', '$isdn', '$pcs', '$pref', '$number'},
+       els = [#spec{name = <<"HOME">>, label = '$home',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"WORK">>, label = '$work',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"VOICE">>, label = '$voice',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"FAX">>, label = '$fax',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PAGER">>, label = '$pager',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"MSG">>, label = '$msg',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"CELL">>, label = '$cell',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"VIDEO">>, label = '$video',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"BBS">>, label = '$bbs',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"MODEM">>, label = '$modem',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"ISDN">>, label = '$isdn',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PCS">>, label = '$pcs',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PREF">>, label = '$pref',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"NUMBER">>, label = '$number',
+                    min = 1, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_email,
+ #spec{name = <<"EMAIL">>, label = '$email',
+       result = {vcard_email, '$home', '$work',
+                '$internet', '$pref', '$x400', '$userid'},
+       els = [#spec{name = <<"HOME">>, label = '$home',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"WORK">>, label = '$work',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"INTERNET">>, label = '$internet',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"PREF">>, label = '$pref',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"X400">>, label = '$x400',
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"USERID">>, label = '$userid',
+                    min = 1, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_geo,
+ #spec{name = <<"GEO">>, label = '$geo',
+       min = 0, max = 1,
+       result = {vcard_geo, '$lat', '$lon'},
+       els = [#spec{name = <<"LAT">>, label = '$lat',
+                    min = 1, max = 1, result = '$cdata'},
+              #spec{name = <<"LON">>, label = '$lon',
+                    min = 1, max = 1, result = '$cdata'}]}}.
+
+{spec, vcard_type,
+ #spec{name = <<"TYPE">>, label = '$type',
+       min = 0, max = 1,
+       result = '$cdata'}}.
+
+{spec, vcard_binval,
+ #spec{name = <<"BINVAL">>, label = '$binval',
+       min = 0, max = 1,
+       cdata = #cdata{dec = {base64, decode, []},
+                      enc = {base64, encode, []}},
+       result = '$cdata'}}.
+
+{spec, vcard_extval,
+ #spec{name = <<"EXTVAL">>, label = '$extval',
+       min = 0, max = 1,
+       result = '$cdata'}}.
+
+{spec, vcard_logo,
+ #spec{name = <<"LOGO">>, label = '$logo',
+       min = 0, max = 1,
+       result = {vcard_logo, '$type', '$binval', '$extval'},
+       els = [vcard_type, vcard_binval, vcard_extval]}}.
+
+{spec, vcard_photo,
+ #spec{name = <<"PHOTO">>, label = '$photo',
+       min = 0, max = 1,
+       result = {vcard_photo, '$type', '$binval', '$extval'},
+       els = [vcard_type, vcard_binval, vcard_extval]}}.
+
+{spec, vcard_org,
+  #spec{name = <<"ORG">>, label = '$org',
+        min = 0, max = 1,
+        result = {vcard_org, '$name', '$units'},
+        els = [#spec{name = <<"ORGNAME">>,
+                     label = '$name',
+                     min = 1, max = 1,
+                     result = '$cdata'},
+               #spec{name = <<"ORGUNIT">>,
+                     label = '$units',
+                     result = '$cdata'}]}}.
+
+{spec, vcard_sound,
+ #spec{name = <<"SOUND">>, label = '$sound',
+       min = 0, max = 1,
+       result = {vcard_sound, '$phonetic', '$binval', '$extval'},
+       els = [vcard_binval, vcard_extval,
+              #spec{name = <<"PHONETIC">>,
+                    min = 0, max = 1,
+                    result = '$cdata'}]}}.
+
+{spec, vcard_key,
+ #spec{name = <<"KEY">>, label = '$key',
+       min = 0, max = 1,
+       result = {vcard_key, '$type', '$cred'},
+       els = [vcard_type,
+              #spec{name = <<"CRED">>,
+                    min = 1, max = 1,
+                    result = '$cdata'}]}}.
+
+{spec, vcard,
+ #spec{name = <<"vCard">>,
+       xmlns = <<"vcard-temp">>,
+       min = 0, max = 1,
+       result = {vcard, '$version', '$fn', '$n', '$nickname', '$photo',
+                 '$bday', '$adr', '$label', '$tel', '$email', '$jabberid',
+                 '$mailer', '$tz', '$geo', '$title', '$role', '$logo',
+                 %% '$agent' XXX: recursive specs are to be implemented
+                 '$org', '$categories', '$note', '$prodid',
+                 '$rev', '$sort-string', '$sound', '$uid', '$url', '$class',
+                 '$key', '$desc'},
+       els = [vcard_name, vcard_adr, vcard_label, vcard_tel,
+              vcard_email, vcard_geo, vcard_logo, vcard_photo,
+              vcard_org, vcard_sound, vcard_key,
+              #spec{name = <<"VERSION">>, label = '$version',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"FN">>, label = '$fn',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"NICKNAME">>, label = '$nickname',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"BDAY">>, label = '$bday',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"JABBERID">>, label = '$jabberid',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"MAILER">>, label = '$mailer',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"TZ">>, label = '$tz',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"TITLE">>, label = '$title',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"ROLE">>, label = '$role',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"CATEGORIES">>, label = '$categories',
+                    default = [],
+                    min = 0, max = 1,
+                    result = '$keywords',
+                    els = [#spec{name = <<"KEYWORD">>,
+                                 label = '$keywords',
+                                 result = '$cdata'}]},
+              #spec{name = <<"NOTE">>, label = '$note',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"PRODID">>, label = '$prodid',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"REV">>, label = '$rev',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"SORT-STRING">>, label = '$sort-string',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"UID">>, label = '$uid',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"URL">>, label = '$url',
+                    min = 0, max = 1, result = '$cdata'},
+              #spec{name = <<"CLASS">>, label = '$class',
+                    min = 0, max = 1,
+                    result = '$value',
+                    els = [#spec{name = <<"PUBLIC">>,
+                                 min = 0, max = 1,
+                                 label = '$value',
+                                 result = public},
+                           #spec{name = <<"PRIVATE">>,
+                                 label = '$value',
+                                 min = 0, max = 1,
+                                 result = private},
+                           #spec{name = <<"CONFIDENTIAL">>,
+                                 label = '$value',
+                                 min = 0, max = 1,
+                                 result = confidential}]},
+              #spec{name = <<"DESC">>, label = '$desc',
+                    min = 0, max = 1, result = '$cdata'}]}}.
+
+{spec, xfield,
+ #spec{name = <<"field">>,
+       label = '$fields',
+       result = {xfield, '$label', '$type', '$var',
+                 '$required', '$desc', '$values', '$options'},
+       attrs = [#attr{name = <<"label">>},
+                #attr{name = <<"type">>,
+                      enc = {enc_enum, []},
+                      dec = {dec_enum, [['boolean',
+                                         'fixed',
+                                         'hidden',
+                                         'jid-multi',
+                                         'jid-single',
+                                         'list-multi',
+                                         'list-single',
+                                         'text-multi',
+                                         'text-private',
+                                         'text-single']]}},
+                #attr{name = <<"var">>}],
+       els = [#spec{name = <<"required">>,
+                    default = false, result = true,
+                    min = 0, max = 1},
+              #spec{name = <<"desc">>,
+                    min = 0, max = 1,
+                    result = '$cdata'},
+              #spec{name = <<"value">>,
+                    label = '$values',
+                    result = '$cdata'},
+              #spec{name = <<"option">>,
+                    label = '$options',
+                    result = '$value',
+                    els = [#spec{name = <<"value">>,
+                                 min = 1, max = 1,
+                                 result = '$cdata'}]}]}}.
+
+{spec, xdata,
+ #spec{name = <<"x">>,
+       label = '$xdata',
+       xmlns = <<"jabber:x:data">>,
+       result = {xdata, '$type', '$instructions', '$title',
+                 '$reported', '$items', '$fields'},
+       attrs = [#attr{name = <<"type">>,
+                      required = true,
+                      dec = {dec_enum, [[cancel, form, result, submit]]},
+                      enc = {enc_enum, []}}],
+       els = [#spec{name = <<"instructions">>,
+                    result = '$cdata'},
+              #spec{name = <<"title">>,
+                    min = 0, max = 1,
+                    result = '$cdata'},
+              #spec{name = <<"reported">>,
+                    min = 0, max = 1,
+                    result = '$fields',
+                    els = [xfield]},
+              #spec{name = <<"item">>,
+                    label = '$items',
+                    result = '$fields',
+                    els = [xfield]},
+              xfield]}}.
+
+{spec, pubsub_subscription,
+ #spec{name = <<"subscription">>,
+       label = '$pubsub_subscriptions',
+       result = {pubsub_subscription, '$jid', '$node', '$subid',
+                 '$type'},
+       attrs = [#attr{name = <<"jid">>,
+                      required = true,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}},
+                #attr{name = <<"node">>},
+                #attr{name = <<"subid">>},
+                #attr{name = <<"subscription">>,
+                      label = '$type',
+                      dec = {dec_enum, [[none, pending, subscribed,
+                                         unconfigured]]},
+                      enc = {enc_enum, []}}]}}.
+
+{spec, pubsub_affiliation,
+ #spec{name = <<"affiliation">>,
+       label = '$pubsub_affiliations',
+       result = {pubsub_affiliation, '$node', '$type'},
+       attrs = [#attr{name = <<"node">>,
+                      required = true},
+                #attr{name = <<"affiliation">>,
+                      label = '$type',
+                      required = true,
+                      dec = {dec_enum, [[member, none, outcast, owner,
+                                         publisher, 'publish-only']]},
+                      enc = {enc_enum, []}}]}}.
+
+{spec, pubsub_item,
+ #spec{name = <<"item">>,
+       result = {pubsub_item, '$id', '$_els'},
+       attrs = [#attr{name = <<"id">>}]}}.
+
+{spec, pubsub_items,
+ #spec{name = <<"items">>,
+       result = {pubsub_items, '$node', '$max_items',
+                 '$subid', '$item'},
+       attrs = [#attr{name = <<"max_items">>,
+                      dec = {dec_int, [0, infinity]},
+                      enc = {enc_int, []}},
+                #attr{name = <<"node">>,
+                      required = true},
+                #attr{name = <<"subid">>}],
+       els = [pubsub_item]}}.
+
+{spec, pubsub_event,
+ #spec{name = <<"event">>,
+       min = 0, max = 1,
+       xmlns = <<"http://jabber.org/protocol/pubsub#event">>,
+       result = {pubsub_event, '$items'},
+       els = [pubsub_items]}}.
+
+{spec, pubsub,
+ #spec{name = <<"pubsub">>,
+       xmlns = <<"http://jabber.org/protocol/pubsub">>,
+       result = {pubsub, '$subscriptions', '$affiliations', '$publish',
+                 '$subscribe'},
+       min = 0, max = 1,
+       els = [#spec{name = <<"subscriptions">>,
+                    min = 0, max = 1,
+                    result = {'$node', '$pubsub_subscriptions'},
+                    attrs = [#attr{name = <<"node">>,
+                                   default = none}],
+                    els = [pubsub_subscription]},
+              #spec{name = <<"affiliations">>,
+                    min = 0, max = 1,
+                    result = '$pubsub_affiliations',
+                    els = [pubsub_affiliation]},
+              #spec{name = <<"subscribe">>,
+                    min = 0, max = 1,
+                    result = {'$node', '$jid'},
+                    attrs = [#attr{name = <<"node">>},
+                             #attr{name = <<"jid">>,
+                                   required = true,
+                                   dec = {dec_jid, []},
+                                   enc = {enc_jid, []}}]},
+              #spec{name = <<"publish">>,
+                    min = 0, max = 1,
+                    result = {'$node', '$item'},
+                    attrs = [#attr{name = <<"node">>,
+                                   required = true}],
+                    els = [pubsub_item]}]}}.
+
+{spec, delay,
+ #spec{name = <<"delay">>,
+       min = 0, max = 1,
+       xmlns = <<"urn:xmpp:delay">>,
+       result = {delay, '$stamp', '$from'},
+       attrs = [#attr{name = <<"stamp">>,
+                      required = true,
+                      dec = {dec_utc, []},
+                      enc = {enc_utc, []}},
+                #attr{name = <<"from">>,
+                      dec = {dec_jid, []},
+                      enc = {enc_jid, []}}]}}.
+
+dec_tzo(Val) ->
+    [H1, M1] = str:tokens(Val, <<":">>),
+    H = erlang:binary_to_integer(H1),
+    M = erlang:binary_to_integer(M1),
+    if H >= -12, H =< 12, M >= 0, M < 60  ->
+            {H, M}
+    end.
+
+enc_tzo({H, M}) ->
+    Sign = if H >= 0 ->
+                   <<>>;
+              true ->
+                   <<"-">>
+           end,
+    list_to_binary([Sign, io_lib:format("~2..0w:~2..0w", [H, M])]).
+
+dec_utc(Val) ->
+    {_, _, _} = jlib:datetime_string_to_timestamp(Val).
+
+enc_utc(Val) ->
+    jlib:now_to_utc_string(Val).
+
+dec_jid(Val) ->
+    case jlib:string_to_jid(Val) of
+        error ->
+            erlang:error(badarg);
+        J ->
+            J
+    end.
+
+enc_jid(J) ->            
+    jlib:jid_to_string(J).
+
+resourceprep(R) ->
+    case jlib:resourceprep(R) of
+        error ->
+            erlang:error(badarg);
+        R1 ->
+            R1
+    end.
+
+dec_bool(<<"false">>) -> false;
+dec_bool(<<"true">>) -> true.
+
+enc_bool(false) -> <<"false">>;
+enc_bool(true) -> <<"true">>.
+
+%% Local Variables:
+%% mode: erlang
+%% End:
+%% vim: set filetype=erlang tabstop=8:
diff --git a/vars.config.in b/vars.config.in
new file mode 100644 (file)
index 0000000..31c356f
--- /dev/null
@@ -0,0 +1,51 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%% @copyright (C) 2013, Evgeniy Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created :  8 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
+%%%-------------------------------------------------------------------
+%% Macros
+{roster_gateway_workaround, @roster_gateway_workaround@}.
+{transient_supervisors, @transient_supervisors@}.
+{full_xml, @full_xml@}.
+{nif, @nif@}.
+{db_type, @db_type@}.
+{debug, @debug@}.
+{hipe, @hipe@}.
+
+%% Ad-hoc directories with source files
+{tools, @tools@}.
+
+%% Dependencies
+{odbc, @odbc@}.
+{mysql, @mysql@}.
+{pgsql, @pgsql@}.
+{pam, @pam@}.
+{zlib, @zlib@}.
+{stun, @stun@}.
+{json, @json@}.
+{http, @http@}.
+{lager, @lager@}.
+{iconv, @iconv@}.
+
+%% Version
+{vsn, "@PACKAGE_VERSION@"}.
+
+%% Variables for overlay template files
+
+%% Platform-specific installation paths
+{release, true}.
+{release_dir, "${SCRIPT_DIR%/*}"}.
+{sysconfdir, "{{release_dir}}/etc"}.
+{installuser, "@INSTALLUSER@"}.
+{erl, "{{release_dir}}/{{erts_vsn}}/bin/erl"}.
+{localstatedir, "{{release_dir}}/var"}.
+{libdir, "{{release_dir}}/lib"}.
+{docdir, "{{release_dir}}/doc"}.
+
+%% Local Variables:
+%% mode: erlang
+%% End:
+%% vim: set filetype=erlang tabstop=8:
similarity index 100%
rename from src/win32/CheckReqs.ini
rename to win32/CheckReqs.ini
similarity index 100%
rename from src/win32/CheckUser.ini
rename to win32/CheckUser.ini
similarity index 100%
rename from src/win32/ejabberd.cfg
rename to win32/ejabberd.cfg
similarity index 100%
rename from src/win32/ejabberd.ico
rename to win32/ejabberd.ico
similarity index 100%
rename from src/win32/ejabberd.nsi
rename to win32/ejabberd.nsi
similarity index 100%
rename from src/win32/inetrc
rename to win32/inetrc